Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

eine verrückte sache mit string und clipboard

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
robbifan



Anmeldungsdatum: 18.05.2007
Beiträge: 43

BeitragVerfasst am: 26.05.2007, 19:32    Titel: eine verrückte sache mit string und clipboard Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Dusky_Joe



Anmeldungsdatum: 07.01.2005
Beiträge: 1007
Wohnort: Regensburg/Oberpfalz

BeitragVerfasst am: 26.05.2007, 23:04    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
robbifan



Anmeldungsdatum: 18.05.2007
Beiträge: 43

BeitragVerfasst am: 27.05.2007, 09:41    Titel: Antworten mit Zitat

Zitat:

Wieso eigentlich 32000?


grösser werden die bilddaten nicht.

mfg
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
robbifan



Anmeldungsdatum: 18.05.2007
Beiträge: 43

BeitragVerfasst am: 27.05.2007, 11:25    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Dusky_Joe



Anmeldungsdatum: 07.01.2005
Beiträge: 1007
Wohnort: Regensburg/Oberpfalz

BeitragVerfasst am: 28.05.2007, 13:24    Titel: Antworten mit Zitat

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 happy



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
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
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.

 Impressum :: Datenschutz