 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
robbifan
Anmeldungsdatum: 18.05.2007 Beiträge: 43
|
Verfasst am: 26.05.2007, 19:32 Titel: eine verrückte sache mit string und clipboard |
|
|
ich habe hier ein programm für writeclipboard und readclipboard :
Code: |
#define CF_TEXT 1
#define GMEM_MOVEABLE &H2
#define GMEM_SHARE &H2000
Declare Function GlobalSize Lib "kernel32" Alias "GlobalSize" (ByVal hMem As Integer) As Integer
Declare Function GlobalUnlock Lib "kernel32" Alias "GlobalUnlock" (ByVal hMem As Integer) As Integer
Declare Function GlobalLock Lib "kernel32" Alias "GlobalLock" (ByVal hMem As Integer) As Integer
Declare Function GlobalAlloc Lib "kernel32" Alias "GlobalAlloc" (ByVal wFlags As Integer, ByVal dwBytes As Integer) As Integer
Declare Function lstrcpyA Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As integer) As Integer
Declare Function lstrcpyB Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As integer, ByVal lpString2 As String) As Integer
Declare Function CloseClipboard Lib "user32" alias "CloseClipboard" () As Integer
Declare Function EmptyClipboard Lib "user32" alias "EmptyClipboard" () As Integer
Declare Function SetClipboardData Lib "user32" alias "SetClipboardData" (ByVal wFormat As Integer, ByVal hMem As Integer) As Integer
Declare Function OpenClipboard Lib "user32" Alias "OpenClipboard" (ByVal hwnd As Integer) As Integer
Declare Function GetClipboardData Lib "user32" Alias "GetClipboardData" (ByVal wFormat As Integer) As Integer
Declare sub WRITEclipboard()
Declare function READclipboard() as string
dim Shared a As String * 32000
Dim Shared text As string * 32000
do
input a
WRITEclipboard()
sleep
? READclipboard()
loop
sub WRITEclipboard()
dim lpMem as integer
Dim hGlobalClip as integer
hGlobalClip = GlobalAlloc(GMEM_MOVEABLE Or GMEM_SHARE, 32000)
OpenClipboard(0)
EmptyClipboard()
lpMem=GlobalLock(hGlobalClip)
lstrcpyB(lpMem, a)
GlobalUnlock(lpMem)
SetClipboardData (CF_TEXT, hGlobalClip)
CloseClipboard()
end sub
function READclipboard() as string
dim hGlobal as integer
dim pGlobal as integer
OpenClipboard(0)
hGlobal = GetClipboardData(1)
if hGlobal then
pGlobal = GlobalLock(hGlobal)
lstrcpyA(text, pGlobal)
READclipboard=text
end if
CloseClipboard ()
end function
|
nun möchte ich dem string ein bereich von
Img = Imagecreate(64, 64, RGBA(64, 160, 0, 255))
übergeben (vorher wurde eine grafik reingezeichnet), und den string dann in das clipboard schreiben und von einem anderen programm wieder rausholen in eine img packen und als bild darstellen.
wer kann mir dabei helfen? |
|
Nach oben |
|
 |
Dusky_Joe

Anmeldungsdatum: 07.01.2005 Beiträge: 1007 Wohnort: Regensburg/Oberpfalz
|
Verfasst am: 26.05.2007, 23:04 Titel: |
|
|
Ich würde einen ZString Ptr benutzen. Reservierde dir mit (C)Allocate erst mal genügend speicher:
Code: | DIM ImgToClip AS ZSTRING
DIM size AS INTEGEr
size = Len(FB.Image) + 64 * 64 * bpp
ImgToClip = Allocate( size ) |
FB.Image ist der Type, der als Header für dein Bild benutzt wird. Du findest ihn in der fbgxf.bi (im Standard-Inc-Verzeichnis von freeBASIC), oder... hier:
Code: | type IMAGE field = 1
union
old as _OLD_HEADER
type as uinteger
end union
bpp as integer
width as uinteger
height as uinteger
pitch as uinteger
_reserved(1 to 12) as ubyte
' '' properties
' declare property pixels() as ubyte ptr
end type |
(Achtung: Wenn du das hier direkt rauskopierst, ist das natürlich nicht mehr Namespace FB!)
Danach kannst du einfach String-Indexing benutzen:
Code: | DIM i AS INTEGER
For i = 0 To size - 1
ImgToClip[i] = Img[i]
Next |
Funktioniert natürlich nur, wenn du Img als Byte Ptr definiert hast. (Normalerweise kannst du den Type deines Puffers beliebig festlegen, interessant wirds nur, wenn du außer mit GET/PUT noch anders darauf zugreifen willst, wie eben hier.)
Sollte das für dich ein Problem darstellen, bitte, hier sei ein Walkaround:
Code: | DIM i AS INTEGER
For i = 0 To size - 1
ImgToClip[i] = Peek( UByte, Img + i )
Next |
Und vergiss nicht, den ZSTRING wieder mit DeAllocate zu löschen!
Aber... tu dir selbst nen Gefallen, und schreibe die Func's so um, dass du nicht mit einer SHARED-Variable a arbeitest, sondern einen Parameter übergibst. Etwa in der Form:
Code: | Function ReadClipboard( readbuffer AS STRING * 32000 ) As String |
Wieso eigentlich 32000?
However, viel Spaß mit dem Code. Hats geklappt?
Mit den Vorgaben solltest du auch in der Lage dazu sein, den ReadClipboard-String wieder in einen Img-Puffer zurückzuverwandeln.
Have a nice day
Ciao
Dusky_Joe _________________ fully biological degradable
Once, the big wave arrives, you've got two ways, you can go:
Either, you ride it, or you don't do.
But, if you don't ride, you'll never know wether you'd have gone wet. |
|
Nach oben |
|
 |
robbifan
Anmeldungsdatum: 18.05.2007 Beiträge: 43
|
Verfasst am: 27.05.2007, 09:41 Titel: |
|
|
Zitat: |
Wieso eigentlich 32000?
|
grösser werden die bilddaten nicht.
mfg |
|
Nach oben |
|
 |
robbifan
Anmeldungsdatum: 18.05.2007 Beiträge: 43
|
Verfasst am: 27.05.2007, 11:25 Titel: |
|
|
klappt soweit mit dem zstring und pointer, gute lösung.
ein hindernis ist jetzt vom clipboard aus, wenn eine "0" gesendet wird dorthin, schließt es den string ab.
also kann man nur text übertragen und keine bytedaten die eine null enthalten, schade.
mfg |
|
Nach oben |
|
 |
Dusky_Joe

Anmeldungsdatum: 07.01.2005 Beiträge: 1007 Wohnort: Regensburg/Oberpfalz
|
Verfasst am: 28.05.2007, 13:24 Titel: |
|
|
Gäbe 2 Walkarounds, sind aber alle Quick'n'Dirty:
A) Du schaltest einfach eine Routine vor, die dein Bild auf Pixel der Farbe 0 (= Schwarz) scannt, und diese durch RGBA(0, 0, 0, 1) ersetzt - das sieht genau so schwarz aus, wird aber durch die Zahl 1 dargestellt.
B) Du zeichnest von haus aus in oben angegebener Farbe (wäre mein bevorzugter Weg).
Anm: Evtl. solltest du den Alpha-Wert 1 durhc 255 ersetzen - je nach dem, was durchsichtiger ist
Nochmal wegen den 32000:
Hab mir fast so was gedacht. Solche Festlegungen solltest du aber weitestmöglich vermeiden. Stell dir vor, du schreibst später ein Prog, in dem du diese Routine wieder verwenden willst, und plötzlich stößt du an die 32KB-Grenze (sind ja nicht mal ganze 32K)
Minimale Änderungen, und das ganze funzt mit jeder beliebigen Bildgröße:
(und wenn ich schon dabei bin, gleich einen dritten Walkaround wegen des CHR(0)-Problems):
Code: | SUB WriteClipboard ( Clip As Any Ptr, ClipLen As Integer )
Dim As Integer lpMem, hGlobalClip
' Reserviere Speicher
hGlobalClip = GlobalAlloc(GMEM_MOVEABLE Or GMEM_SHARE, ClipLen)
' Bereite den Clipboard vor
OpenClipboard(0)
EmptyClipboard()
' Sperre den reserviersten Speicher für's System, um darauf zuzugreifen
lpMem=GlobalLock(hGlobalClip)
' Kopiere Daten von deinem Bildpuffer in den reservierten Bereich
' Diese Zeile ersetzt lstrcpyB(lpMem, a)
CopyMemory lpMem, Clip, ClipLen
' Kontrolle über Speicherberiech zurück ans System
GlobalUnlock(lpMem)
' Daten ins Clipboard schreiben, und Vorgang abschließen
SetClipboardData (CF_DSPTEXT, hGlobalClip)
CloseClipboard()
End Sub |
Dazu gehören dann ein paar andere Def's:
Code: | #Define CF_DSPTEXT 129
Declare Function CopyMemory cdecl alias "memcpy" (ByVal As Any Ptr, ByVal As Any Ptr, ByVal As Integer) As Any Ptr |
Jetzt brauchst du auch keinen ZString Ptr mehr; einfach
Code: | Img = ImageCreate (...)
WriteClipBoard Img, Len(FB.Image) + 64 * 64 * 4 |
(Musst du natürlich an die Größe und bpp deines Bildes anpassen, aber für dieses Bsp sollte es so stimmen.)
Ich bin mir nicht ganz sicher, ob das ganze dann auch bei ReadClip funktioniert. Da ich das momentan nicht testen kann, bzw. auch die nötigen Änderungen nicht mit Sicherheit vorhersagen kann, halte ich mich da erst mal bedeckt. Zu dumm, dass es von M$ kein CF_RAW oder ähnliches gibt...
However, ich würde in WriteClip den zu speichernden String als Parameter übergeben, und dann so etwas machen wie
ClipNen = Len(Clip)
hGlobalClip = GlobalAlloc(GMEM_MOVEABLE Or GMEM_SHARE, ClipLen)
Ah, ja, noch ein Hinweis, der dir Tipparbeit sparen kann:
Anstatt jedes mal in deinen DECLAREs die LIB-Klausel anhängen zu müssen, kannst du's auch einfach so machen:
Code: | Extern "windows" Lib "kernel32"
DECLARE ...
End Extern |
(oder entsprechend LIB "user32")
Have a nice day
Ciao
Dusky_Joe _________________ fully biological degradable
Once, the big wave arrives, you've got two ways, you can go:
Either, you ride it, or you don't do.
But, if you don't ride, you'll never know wether you'd have gone wet. |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|