| |
|
|
- Page 1 - |
|
Jörg Sellmeyer | Ich hab jetzt via Ole (Dank an Andreas Miethe - immer wieder) ein funktionierendes Handle per Bitmaps (auch gif, ico und diverse andere Formate) ermitteln können, das dann ganz normal auf einem Bitmapstatic angezeigt werden kann. Mit der Ermittlung der Dimensione kann ich mich in dem Fall noch nicht ganz anfreunden. Wer da eine Idee hat - im Code ist die Stelle markiert.
Hier jedenfalls erstmal der Code, um ein gültiges Handle auch per grande Bilder zu erhalten. Wenn man es im Programm häufiger verwendet, ist es sicher sinnvoller, die Init-Routine nur einmal am Anfang aufzurufen, aber so funktioniert es schon mal klaglos. Bitte mal mit File größer als 5100 Pixeln testen. Aktuell habe ich es nur mit jpg und gif probiert. Icos sind ja größenmäßig nicht das Problem.
$H windows.ph
'Konstanten
DEF &Picture_Release 8
DEF &Picture_GetHandle 12
DEF &Picture_GetType 20
DEF &Picture_Get_Width 24
DEF &Picture_Get_Height 28
DEF &Picture_Render 32
DEF &Picture_Select 44
'Globale Variablen
DECLARE IID_IPicture#
DECLARE PData#
DECLARE HMEM&
Declare OlePic#
Class OleImage = OleImage@,\
Ole_Init@,\
Ole_Free@,\
Ole_LoadImage@,\
Ole_GetType@,\
Ole_GetHandle@,\
Ole_FreeImage@,\
OLE32&,\
OLEPro32&,\
PictureObject&,\
hPic&,\
PicFormat&,\
Width&,\
Height&,\
GetSize@,\
Destroy@
Proc OleImage.OleImage
Parameters File$
.Ole_Init()
.PictureObject& = .Ole_LoadImage(File$)
.PicFormat& = .Ole_GetType(.PictureObject&)
.hPic& = .Ole_GetHandle()
Print .PictureObject&,.PicFormat&,.hpic&
EndProc
Proc OleImage.Ole_Init
.OLE32& = UseDll("OLE32")
.OLEPRO32& = UseDll("OLEPRO32")
External("OLE32","OleInitialize",0)
Dim IID_IPicture#,16
Long IID_IPicture#,0 = $7BF80980
Word IID_IPicture#,4 = $BF32
Word IID_IPicture#,6 = $101A
Byte IID_IPicture#,8 = $8B
Byte IID_IPicture#,9 = $BB
Byte IID_IPicture#,10 = $00
Byte IID_IPicture#,11 = $AA
Byte IID_IPicture#,12 = $00
Byte IID_IPicture#,13 = $30
Byte IID_IPicture#,14 = $0C
Byte IID_IPicture#,15 = $AB
EndProc
Proc OleImage.Ole_Free
~GlobalFree(Hmem&)
External("OLE32","OleUninitialize")
FreeDll .OLE32&
FreeDll .OLEPRO32&
DISPOSE IID_IPicture#
EndProc
Proc OleImage.Ole_LoadImage
Declare MemPointer&,PStream&,PictureObject&,PSize&
Parameters Picture$
'------------------------
Set("Filemode", 0)
PSIZE& = Filesize(Picture$)
Dim PData#,PSIZE&
BlockRead(Picture$,PData#,0,PSIZE&)'Daten in Bereichsvariable einlesen
'------------------------
~GlobalFree(Hmem&)
HMem& = ~GlobalAlloc($022,PSize&)'Speicher reservieren
Mempointer& = ~GlobalLock(Hmem&)'Pointer auf Speicher
~RtlMoveMemory(MemPointer&,PData#,PSize&)'Bereichsvariable in Speicher schieben
DISPOSE PData#'Bereichsvariable freigeben
~GlobalUnlock(HMem&)'Speicher zum Gebrauch freigeben
External("Ole32","CreateStreamOnHGlobal",Hmem&,1,addr(PStream&))'Stream-Pointer erstellen
External("OlePro32","OleLoadPicture",PStream&,PSIZE&,0,IID_IPicture#,ADDR(PictureObject&))'Pointer fuer Pictureobject
'------------------------
Case PictureObject& > 0 : Return PictureObject&
Case PictureObject& = 0 : Return 0
EndProc
Proc OleImage.Ole_GetType
Declare Command&,PicFormat&
Command& = Long(.PictureObject&,0)
Call(@Long(Command&,&Picture_GetType),.PictureObject&,addr(PicFormat&))
Return PicFormat&
EndProc
Proc OleImage.GetSize
Parameters DC&
Declare Command&,w&,h&,xpixels&,ypixels&
Command& = Long(.PictureObject&,0)
'hier wird die Bildschirmauflösung pro Zoll abgefragt - bei mir 96x96.
'Allerdings weiß ich nicht, welche Funktion in welcher dll da angesprochen wird.
Call(@Long(Command&,&Picture_Get_Width),.PictureObject&,addr(w&))
Call(@Long(Command&,&Picture_Get_Height),.PictureObject&,addr(h&))
'die Dimensione des Fensters wird ermittelt
xpixels& = ~GetDeviceCaps(DC&, 88)
ypixels& = ~GetDeviceCaps(DC&, 90)
'Umrechnung der Bildschirmauflösung auf die Fenstergröße.
'Ich hab allerdings keine Ahnung, wie der Wert 2540 zustande kommt.
.Width& = Round((w&*xpixels&)/2540,0)
.Height& = Round((h&*ypixels&)/2540,0)
EndProc
Proc OleImage.Ole_GetHandle
Declare Command&,PicHandle&
Command& = Long(.PictureObject&,0)
Call(@Long(Command&,&Picture_GetHandle),.PictureObject&,addr(PicHandle&))
Return PicHandle&
EndProc
Proc OleImage.Ole_FreeImage
Parameters PictureObject&
Declare Command&
Command& = Long(PictureObject&,0)
Call(@Long(Command&,&Picture_Release),PictureObject&)
EndProc
Proc OleImage.Destroy
DeleteObject .hPic&,.PictureObject&
.Ole_Free()
EndProc
Declare hbtn&,Bild$,hFont&,Anzeige&,OleAnzeige&,TestHandle&
UserMessages $10
~SetWindowLong(%hwnd,~GWL_STYLE,(~GetWindowLong(%hwnd,~GWL_STYLE) | $300000))
Window %maxx,%maxy
WindowTitle "Handle per OLE"
hFont& = Create("Font","Western ",14,0,0,0,0)
SetDialogFont hFont&
hbtn& = Create("Button",%hwnd,"Bild laden",%maxx-80,40,60,24)
WhileNot %key = 27'ESC beendet das Programm
If GetText$(%hwnd) <> "Handle per OLE"
WaitInput 4000
WindowTitle "Handle per OLE"
ShowWindow(hbtn&,5)
EndIf
WaitInput
Case %uMessage = $10:Break
If Clicked(hbtn&)
Bild$ = LoadFile$("ÖFFNE","alle unterstützten Formate|*.dib;*.bmp;*.rle;*.jpe;*.jpeg;*.jpg;*.gif;*.ico;*.cur;*.emf;*.wmf|\
Bitmap (bmp,rle,dib)|*.bmp;*.rle;*.dib|Jpeg (jpg,jpe,jpeg)|*.jpg;*.jpe;*.jpeg|Gif (gif)|*.gif|\
Enhanced Metafile (emf)|*.emf|Metafile (wmf)|*.wmf|Icons (Ico)|*.ico|Cursor (cur)|*.cur")
If Bild$ > ""
TestHandle& = Create("hPic",-1,Bild$)
'bei grande Bildern ist hier das Ergebnis 0
WindowTitle Str$(TestHandle&) + " Bei sehr grande Bildern ist das Ergebnis hier 0"
DeleteObject TestHandle&
If SizeOf(OlePic#)
DestroyWindow(OleAnzeige&)
OlePic#.Destroy()
Dispose OlePic#
EndIf
OlePic# = New(OleImage,Bild$)
If Anzeige&
DestroyWindow(Anzeige&)
waitinput
Cls
EndIf
With OlePic#
'die Handleermittlung via Ole bringt ein verwertbares Handle:
OlePic#.GetSize(%hdc2)
Print .Width&,.Height&,"Typ:",.Ole_GetType()
If .PicFormat& = 1
OleAnzeige& = Create("Bitmap",%hwnd,.hPic&,0,0)
.GetSize(%hdc2)
Print .Width&,OlePic#.Height&
ElseIf .PicFormat& = 3
Print "Icon ist Typ:",.PicFormat&,"und kann schneller mit Profanmitteln angezeigt werden."
EndIf
EndWith
EndIf
EndIf
Wend
If SizeOf(OlePic#)
OlePic#.Destroy()
Dispose OlePic#
EndIf
DeleteObject hFont&
End
Basierend auf diesem Code [...] von Andreas Methe |
|
|
| Windows XP SP2 XProfan X4... und hier mal was ganz anderes als Profan ... | 03.06.2020 ▲ |
|
|
|
|
| |
|
- Page 2 - |
|
RGH | Gerade getestet: Mit Matthias' Code (reines XProfan) konnte ich meine größten Bilder (16 MPixel, Dateigröße circa 6 MB) problemlos laden. Größere Bilder habe ich nicht. Ich benutze meine aktuelle XProfan-Version.
Nachtrag: Und auch das oben verlinkte Afrika-Bild macht in höchster Auflösung (75 MPixel) keine Probleme.
Saluto Roland |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 11.06.2020 ▲ |
|
|
|
|
Matthias Arlt | Ich hatte mit 11.2 getestet und Jörg vmtl. mit X4. Dann scheinen da wohl noch andere Faktoren eine Rolle zu spielen...nur welche? Mir war das ja auch noch nie aufgefallen, da ich solch grande Bilder eben auch nicht habe. Ach ja...wenn FreeProfan und OLE sich nicht so recht mögen...meine "schlankere" API-Variante kommt ja ganz ohne OLE aus. |
|
|
| WinXP SP2, Win7 - XProfan 10/11/FreeProfan32 - Xpia | 11.06.2020 ▲ |
|
|
|
|
Jörg Sellmeyer | RGH (11.06.2020)
Ich habe gerade mal nachgeschaut: Die XProfan-Befehle und -Funktionen, die Bilder aus File laden (MLoadBmp, DrawPic, DrawSizedPic und Create("hPic",...)), nutzen eine OLE-Routine, die an Andreas' Code angelehnt ist. Hier sollte es keine Probleme mit grande Bitmaps geben. Ich muss das mal näher überprüfen.
(Das gilt nicht per FreeProfan, da ich FreePascal noch nicht mit OLE-Objekten verheiraten konnte.)
Saluto Roland
RGH
Nachtrag: Und auch das oben verlinkte Afrika-Bild macht in höchster Auflösung (75 MPixel) keine Probleme.
Da frage ich mich aber, warum das bei mir nicht funktioniert. Ich hab zwar noch XP mit 2GB Ram aber mit meiner Variante von Andreas' Code funktioniert es ja, also kann es nicht generell am Speicher oder der Windowsversion liegen. Vielleicht kannst du nochmal schauen, was da die Unterschiede in deiner Version zu meiner sind. Der verschlankte Code von Matthias funktioniert bei mir übrigens auch nicht.
Außerdem fällt mir auf, dass Matthias print verwendet, um das Bild zu verarbeiten. Das wird in meinem Code vermieden, sondern nur durch Speicherschiebereien das Handle ermittelt. |
|
|
| Windows XP SP2 XProfan X4... und hier mal was ganz anderes als Profan ... | 11.06.2020 ▲ |
|
|
|
|
Matthias Arlt | @Jörg Ich habe hier auf diesem PC ja auch XP SP2 drauf. Nachdem nun Roland keine Probleme beim Laden des Bildes hatte, hab ich das Ganze mal schnell in einem virtuellen Win 7 probiert. Und siehe da...dort gibt es auch kein Problem!
Wenn sich nun der profaninterne Code lt. Roland an das OLE-Prozedere von Andreas anlehnt, muß es aber doch Unterschiede geben, denn extern funtioniert es ja mittels OLE.
Das print in meinem Code steht dort eigentlich nur, weil ich das Handle angezeigt bekommen wollte. Warum aber diese API-Variante, die eigentlich nur GDI(+)-Funktionen nutzt, bei Dir nicht geht, ist mir nun wieder ein Rätsel.
Mysteriös...aber immerhin einen Schritt weiter... |
|
|
| WinXP SP2, Win7 - XProfan 10/11/FreeProfan32 - Xpia | 11.06.2020 ▲ |
|
|
|
|
Jörg Sellmeyer | Ich habs jetzt auch auf nem Laptop mit Win7 und 4GB Ram getestet und es funktioniert mit deinem Code. Das erklärt aber immer noch nicht, warum es bei mir mit meinem Code auch auf mkeinem minderbemittelten Rechner funktioniert aber nicht mit deinem Code. |
|
|
| |
|
|
|
Matthias Arlt | Das ist ja das Mysterium...
GDI+ sollte bei XP ja standardmäßig vorhanden sein. Das ist es also vmtl. nicht. Du könntest vlt. mal die Rückgabewerte schrittweise per jeden Funktionsaufruf ansehen. Eventuell führt das etwas weiter !?
Festhalten können wir jedenfalls, daß sich create("hPic" unter XP (und wohl nur dort) bei Bildern von annähernd 8000x8000 untypisch verhält. Kein Problem, wenn man das weiß oder solche Bilder nicht hat.
Den folgenden Passus kannst Du auch aus der OLE-Variante entfernen:
TestHandle& = Create("hPic",-1,Bild$) WindowTitle Str$(TestHandle&) + " Bei sehr grande Bildern ist das Ergebnis hier 0" DeleteObject TestHandle&
OLE kommt ohne ihn aus und necessario ihn nicht (systemunabhängig). Deshalb ist er dort m.E. auch nicht hilfreich (und stiftet vlt. Verwirrung). |
|
|
| WinXP SP2, Win7 - XProfan 10/11/FreeProfan32 - Xpia | 11.06.2020 ▲ |
|
|
|
| |
|
- Page 3 - |
|
|
Jörg Sellmeyer | Der Code ist weit davon entfernt, als lauffähiger/nutzbarer Code zu dienen. Bisher dient er nur zu Test- und Anschauungszwecken. |
|
|
| |
|
|
|
Matthias Arlt | Allein so wie er ist vlt. weniger aber als ausbaufähige Basis schon. Das was er tun soll "Laden und Anzeigen" klappt doch problemlos. |
|
|
| WinXP SP2, Win7 - XProfan 10/11/FreeProfan32 - Xpia | 11.06.2020 ▲ |
|
|
|
|
RGH | Ich weiß nicht, ob man Energie per Probleme verwenden sollte, die nur beim wirklich veralteten Windows XP auftreten ... zumal ich keine Möglichkeit mehr habe, unter XP zu testen.
Saluto Roland |
|
|
| XProfan X4Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 11.06.2020 ▲ |
|
|
|
|
Matthias Arlt | @Roland Nein, ich sehe da auch keinen Handlungsbedarf, nachdem das Problem erkannt und eingegrenzt ist und es funktionierende Workarrounds gibt.
Mit dem veraltet bei XP ist das hin und wieder nicht so einfach. Für bestimmte technische Anwendungen ist XP manchmal schon sowas wie der kleinste gemeinsame Nenner, um unverhältnismäßigen Aufwand zu vermeiden. |
|
|
| WinXP SP2, Win7 - XProfan 10/11/FreeProfan32 - Xpia | 11.06.2020 ▲ |
|
|
|
|
Jörg Sellmeyer | @Roland; Natürlich kann Io l' Standpunkt verstehen - richtig akzeptieren kann ich die Einstellung nicht.
Es geht hier nicht (nur) um eine veraltete Windowsversion, sondern um ein Programm. was an einer Stelle unnötig Resourcen verbrät. Da kann man sich leicht auf den Standpunkt zurückziehen, soll der Kunde sich doch was Neues/Notizie kaufen, dann corre es auch wieder. Das ist aber eine Einstellung, die mittlerweile dazu geführt hat, dass PC, die früher High-End-Maschinen waren, heutzutage, kaum noch als Bürocomputer taugen, weil selbst die Schreibprogramm so verschwenderisch mit Plattenplatz und Ram umgehen, dass alle zwei Jahre ein neuer PC hermuss, wenn man bei dieser Software Uptodate sein will. Profan ist zu Glück weit entfernt von solch absurden Auswüchsen, aber es bietet sich an, dem Pfad treu zu bleiben, wenn es doch offensichtlich eine Alternative gibt, die ja anscheinend gar nicht soweit entfernt von den ohnehin eingebauten Codeteilen zu sein scheint.
Grundlage von meinem Code, ist genau der Code [...] von Andreas. Ich hab das nur in un Klasse gepackt, weil mir das Format gefällt. Der einzige Unterschied ist, dass ich das Bild nicht mit den Olemitteln auf den Bildschirm bringe, sondern das Handle nutze, um es weiter mit Profanmitteln zu verarbeiten. Vielleicht ist das ja schon der Punkt, wo in deinem Code eine kleine Cambiamento Wunder bewirken potuto. |
|
|
| |
|
|
|
Matthias Arlt | Ich hab den "schlanken" Code nochmal überarbeitet. Da waren im Eifer des Probierens 2 Profan-Befehle drin geblieben, die in die API-Routine nicht hineingehören. |
|
|
| WinXP SP2, Win7 - XProfan 10/11/FreeProfan32 - Xpia | 12.06.2020 ▲ |
|
|
|