Problem mit Sendkeys() in Word/Excel

Anfängerfragen zum Programmieren mit PureBasic.
Lord
Beiträge: 324
Registriert: 21.01.2008 19:11

Beitrag von Lord »

Wo gibt's denn diese 30 cm breiten Briefmarken? :)
Bild
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Ist heute heute Tag der beschissenen Kalauer? :?
Windows 10 Pro, 64-Bit / Outtakes | Derek
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

Kaeru, bitte nicht böse sein, aber ich konnte einfach nicht anders. :wink:
Auch wenn dieses keybd_event nur eine Notlösung ist, muß ich wissen
weshalb dieser Fehler nur im ersten zweiten Feld auftritt und
nirgendwo sonst.
Ich hab für das schreiben in die integrierte Exceltabelle, den Code zum Teil komplett umgeschrieben.
Jetzt stoppt es beim Schreiben, wenn Windows oder ein anderes Programm
etwas zwischenspeichert und schreibt danach ohne Probleme weiter.
Nur in dem ersten zweiten Feld verschluckt er immer wiedermal noch Zeichen. :|
Wie kann das sein?
Hier ist ein Auszug von dem umgeschriebenen Programm:

Code: Alles auswählen

Procedure ShiftRunter(STR.s)
Shared Mtx
  Repeat
    If TryLockMutex(Mtx)
      Break
    EndIf
  ForEver
Select STR
  Case "°"
   VK.w = #VK_RIGHT
  Case "^"
   VK.w = #VK_LEFT
  Case "|"
   VK.w = #VK_DOWN
  Default
   VK.w = VkKeyScan_(Asc(STR))
   ;VK.w = VkKeyScanEx_(Asc(Key),GetKeyboardLayout_(0))
EndSelect
Shift.l = VK & $100
If Shift
     keybd_event_(#VK_SHIFT, 0, 0, 0)
EndIf  

UnlockMutex(Mtx)

EndProcedure

Procedure ShiftHoch(STH.s)
Shared Mtx
  Repeat
    If TryLockMutex(Mtx)
      Break
    EndIf
  ForEver
Select STH
  Case "°"
   VK.w = #VK_RIGHT
  Case "^"
   VK.w = #VK_LEFT
  Case "|"
   VK.w = #VK_DOWN
  Default
   VK.w = VkKeyScan_(Asc(STH))
   ;VK.w = VkKeyScanEx_(Asc(Key),GetKeyboardLayout_(0))
EndSelect
Shift.l = VK
If Shift
     keybd_event_(#VK_SHIFT, 0, #KEYEVENTF_KEYUP, 0)
EndIf
    
UnlockMutex(Mtx)
EndProcedure

Procedure StrgRunter(SGTR.s)
Shared Mtx
  Repeat
    If TryLockMutex(Mtx)
      Break
    EndIf
  ForEver
Select SGTR
  Case "°"
   VK.w = #VK_RIGHT
  Case "^"
   VK.w = #VK_LEFT
  Case "|"
   VK.w = #VK_DOWN
  Default
   VK.w = VkKeyScan_(Asc(SGTR))
   ;VK.w = VkKeyScanEx_(Asc(Key),GetKeyboardLayout_(0))
EndSelect
Ctrl.l = VK & $200
If Ctrl
     keybd_event_(#VK_CONTROL, 0, 0, 0)
EndIf  
UnlockMutex(Mtx)
EndProcedure

Procedure StrgHoch(SGTH.s)
Shared Mtx
  Repeat
    If TryLockMutex(Mtx)
      Break
    EndIf
  ForEver
  Select SGTH
  Case "°"
   VK.w = #VK_RIGHT
  Case "^"
   VK.w = #VK_LEFT
  Case "|"
   VK.w = #VK_DOWN
  Default
   VK.w = VkKeyScan_(Asc(SGTH))
   ;VK.w = VkKeyScanEx_(Asc(Key),GetKeyboardLayout_(0))
EndSelect
Ctrl.l = VK
If Ctrl
     keybd_event_(#VK_CONTROL, 0, #KEYEVENTF_KEYUP, 0)
EndIf
  

UnlockMutex(Mtx)
EndProcedure

Procedure AltRunter(ATR.s)
Shared Mtx

Repeat
  If TryLockMutex(Mtx)
    Break
  EndIf
ForEver
Select ATR
  Case "°"
   VK.w = #VK_RIGHT
  Case "^"
   VK.w = #VK_LEFT
  Case "|"
   VK.w = #VK_DOWN
  Default
   VK.w = VkKeyScan_(Asc(ATR))
   ;VK.w = VkKeyScanEx_(Asc(Key),GetKeyboardLayout_(0))
EndSelect
Alt.l = VK & $400
If Alt
     keybd_event_(#VK_MENU, 0, 0, 0)
EndIf
  
UnlockMutex(Mtx)
EndProcedure

Procedure AltHoch(ATH.s)
Shared Mtx

Repeat
  If TryLockMutex(Mtx)
    Break
  EndIf
ForEver
Select ATH
  Case "°"
   VK.w = #VK_RIGHT
  Case "^"
   VK.w = #VK_LEFT
  Case "|"
   VK.w = #VK_DOWN
  Default
   VK.w = VkKeyScan_(Asc(ATH))
   ;VK.w = VkKeyScanEx_(Asc(Key),GetKeyboardLayout_(0))
EndSelect
Alt.l = VK
If Alt
     keybd_event_(#VK_MENU, 0, #KEYEVENTF_KEYUP, 0)
EndIf
  
UnlockMutex(Mtx)
EndProcedure

Procedure KeyDown(Runter.s)
  Shared Mtx
  Repeat
    If TryLockMutex(Mtx)
      Break
    EndIf
  ForEver
  ;SetPriorityClass_(GetCurrentProcess_(),#REALTIME_PRIORITY_CLASS)
  
  Select Runter
  Case "°"
   VK.w = #VK_RIGHT
  Case "^"
   VK.w = #VK_LEFT
  Case "|"
   VK.w = #VK_DOWN
  Default
   VK.w = VkKeyScan_(Asc(Runter))
   ;VK.w = VkKeyScanEx_(Asc(Key),GetKeyboardLayout_(0))
EndSelect
;If VK = -1
;ProcedureReturn
;EndIf
If MapVirtualKey_(VK, 2) = 0
  Extended.l = #KEYEVENTF_EXTENDEDKEY
  Scan.l = MapVirtualKey_(VK, 0)
Else
  Extended = 0
  Scan = 0
EndIf
  
  VK & $FF
  keybd_event_(VK, Scan, Extended, 0)
  ;SetPriorityClass_(GetCurrentProcess_(),#NORMAL_PRIORITY_CLASS)
  UnlockMutex(Mtx)
  EndProcedure

Procedure KeyUp(Hoch.s)
  Shared Mtx
  
  Repeat
    If TryLockMutex(Mtx)
      Break
    EndIf
  ForEver
  
  Select Hoch
  Case "°"
   VK.w = #VK_RIGHT
  Case "^"
   VK.w = #VK_LEFT
  Case "|"
   VK.w = #VK_DOWN
  Default
   VK.w = VkKeyScan_(Asc(Hoch))
   ;VK.w = VkKeyScanEx_(Asc(Key),GetKeyboardLayout_(0))
EndSelect
;If VK = -1
;ProcedureReturn
;EndIf
If MapVirtualKey_(VK, 2) = 0
  Extended.l = #KEYEVENTF_EXTENDEDKEY
  Scan.l = MapVirtualKey_(VK, 0)
Else
  Extended = 0
  Scan = 0
EndIf
  
  keybd_event_(VK, Scan, #KEYEVENTF_KEYUP | Extended, 0)
  UnlockMutex(Mtx)
  EndProcedure

Mtx = CreateMutex()

Structure InTabelle
    RS.s
    EndStructure
    
    Dim EW.InTabelle(0)
     ForEach Liste()
                
        If CountString(Liste(), "x") > 0
        Stueckzahl.q = ValQ(ReplaceString(Liste(), "x", ""))
        Stueckz.s = StrQ(Stueckzahl.q)
        EW(0)\RS + Stueckz
        Else
        Stueckz.s = Liste()
        EW(0)\RS + Stueckz
        EndIf
        
        EW(0)\RS + "°"
        
        NextElement(Liste())
        Artnr.s = Liste()
        EW(0)\RS + Artnr
        EW(0)\RS + "°"
        NextElement(Liste())
        Marke.s  = Liste()
        EW(0)\RS + Marke
        EW(0)\RS + "°"
        EW(0)\RS + "C"
        EW(0)\RS + "°"
        NextElement(Liste())
        Format.s = Liste()
        EW(0)\RS + Format
        EW(0)\RS + "°"
        NextElement(Liste())
        If CountString(Liste(), ",") > 0 
          Einzelpreis.q = ValQ(ReplaceString(Liste(), ",", ""))
          Epreis.s = Liste()
          EW(0)\RS + Epreis
          EW(0)\RS + "°"
        EndIf
        
        NextElement(Liste())
        VPE.s = Liste()
        EW(0)\RS + VPE
        ;EW(0)\RS + "°"
        NextElement(Liste())

        If GetGadgetState(16) = 1
          Einzelpreis.q * Stueckzahl.q
          Summe.q + Einzelpreis.q
          Gesamtpreis.s = ReplaceString(StrQ(Einzelpreis.q), Right(StrQ(Einzelpreis.q), 2), "," + Right(StrQ(Einzelpreis.q), 2))
          EW(0)\RS + "°"
          EW(0)\RS + Gesamtpreis
          EW(0)\RS + "^"
        EndIf
        
        EW(0)\RS + "^^^^^^"
        EW(0)\RS + "|"
                
     Next
  For H = 0 To Len(EW(0)\RS)-1
    Prozess1 = CreateThread(@ShiftRunter(), Mid(EW(0)\RS, H, 1))
               WaitThread(Prozess1)
  
    Prozess2 = CreateThread(@StrgRunter(), Mid(EW(0)\RS, H, 1))
               WaitThread(Prozess2)
  
    Prozess3 = CreateThread(@AltRunter(), Mid(EW(0)\RS, H, 1))
               WaitThread(Prozess3)
            
    Prozess4 = CreateThread(@KeyDown(), Mid(EW(0)\RS, H, 1))
               WaitThread(Prozess4)
            
    Prozess5 = CreateThread(@KeyUp(), Mid(EW(0)\RS, H, 1))
               WaitThread(Prozess5)
            
    Prozess6 = CreateThread(@ShiftHoch(), Mid(EW(0)\RS, H, 1))
               WaitThread(Prozess6)
            
    Prozess7 = CreateThread(@StrgHoch(), Mid(EW(0)\RS, H, 1))
               WaitThread(Prozess7)
            
    Prozess8 = CreateThread(@AltHoch(), Mid(EW(0)\RS, H, 1))
               WaitThread(Prozess8)
     
  Next H
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

Fluid Byte hat geschrieben:Ist heute heute Tag der beschissenen Kalauer? :?
kann sein, denn heute, also gestern - morgen, ist Europawahl...

kann man eigentlich für die Piraten kreutzchenmachen?
Auch wenn dieses keybd_event nur eine Notlösung ist, muß ich wissen
weshalb dieser Fehler nur im ersten zweiten Feld auftritt und
nirgendwo sonst.
bo-ah

keine ahnung, warum dein aus einem stück geschnitztes holzrad am porsche nich rundläuft,
vielleicht solltest du doch eine leiste dampfbiegen für den lauf,
und die speichen faserlängs schnitzen,
aber trotzdem solltest du nich zu hohen drehmoment draufprügeln...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

Kaeru Gaman hat geschrieben: ...aber trotzdem solltest du nich zu hohen drehmoment draufprügeln...
Mach ich doch auch nicht. <)
Und ich schalte auch ganz vorsichtig: :wink:

...CreateThread(@ShiftHoch()...
Waitthread...

Ich glaube ich weiß jetzt, was das Problem sein könnte.
Wenn ich VK_RIGHT und VK_LEFT herausnehme und sehr lange Zeilen
in das Feld der Exceltabelle formatiere, dann tritt das Problem, beim
ersten verlassen des ersten Feldes auf,
in das ich geschrieben hatte. Wenn ich Glück habe, könnte es funktionieren,
in dem ich nicht direkt aus einem String lese und so Excel nicht
in die Quere komme.
Jetzt ist nur die Frage, wie ich bei Excel nicht unter die Holzräder komme.
<)
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

Ich habe das Programm in soweit fertig geschrieben, das alle Daten erfasst und ausgegeben werden können.
Nun habe ich eine Frage zu Word-Dokumenten.
Habe mir eine mit integrierter Excel-Tabelle in einem Hex-Editor betrachtet.
EMBED Excel.Sheet.8......
Ist das die Verknüpfung mit der Excel-Tabelle, von der ts-soft sprach?
Ich kenne mich mit Word und Excel nicht wirklich aus, vor dem schreiben dieses Programmes noch nie aktiv verwendet.
Oder meinte er, eine Verknüpfung in Word selbst?
PB 4.00 | Windows XP Home SP3
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

Okay, das ist keine Verknüpfung, sondern ein eingebettetes Objekt.
Jetzt hab ich es kapiert. :)
PB 4.00 | Windows XP Home SP3
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

Geht es nur mir so?
Jedesmal wenn ich die Hilfen von Microsoft lese bekomme ich Magenschmerzen.
Weiß vielleicht jemand wo es besser strukturierte Hilfen gibt?
Name reicht, die Addresse finde ich selbst. :wink:
PB 4.00 | Windows XP Home SP3
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

Ich glaube es gibt eine relativ einfache möglichkeit Word-Dokumente(.docx) zu manipulieren, ich muß aber erst noch testen, ob das stimmt was ich gelesen habe und ob es mit PB funktioniert.
Kann dauern. <)
PB 4.00 | Windows XP Home SP3
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

So, ich denke ich habe nur noch ein Hindernis zu nehmen, bevor ich die SendKeys() Funktion in die Tonne hauen kann.
Stand bis jetzt:
Die docx Dateien sind im Unterschied zu den vorherigen doc im Grunde nur gepackte(zip) XML Dateien.

Ich habe als erstes die Endung docx in zip manuell umgeschrieben.
Danach auch manuell entpackt. Das gleiche mit der gepackten Excel-xlsx-Datei.
Um daraus, aus dem Ordner /word/embeddings, die sharedStrings.xml mit PB auf diese Weise zu manipulieren:

Code: Alles auswählen

If OpenFile(0, "...\sharedStrings.xml")
   FileSeek(0, 162)
   WriteString(0, "a")
   CloseFile(0)               
Else
   MessageRequester("Fehler","Dateiuzugriffsfehler!")
EndIf
Zum Schluß, alles wieder komprimiert und Word gestartet, Datei geladen, funktioniert. :)
Jetzt stellt sich mir nur noch die Frage, ist es mit den Packerbefehlen von PB möglich, den gleichen Weg wie manuell zu gehen?
Die Angabe des KompressionsLevel ist der optional oder Pflicht?
Für das manuelle entpacken/packen benutzte ich 7zip.

Danke schon mal für die Mühen und Antworten.
Wenn etwas unklar ist, aufgrund meiner schlechten Erklärung, einfach schreien. :wink:
PB 4.00 | Windows XP Home SP3
Antworten