Imageview und PDF oder Doc

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Imageview und PDF oder Doc

Beitrag von Koverhage »

Hallo,

ich benutze das Sample von Alaska um eingescannte Dokumente anzuzeigen.
Um die Dokumentenverwaltung komplett zu machen, würde ich auch gerne
DOC, PDF und XLS Dateien darin integrieren.
Hat jemand schon mal sowas gemacht oder das Sample so aufgebohrt ?
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Um was für ein Sample geht es?

Beim installierten Office und Adobe Reader kannst du die von dir genannte Dateien mit IE öffnen lassen.
Gruß,

Andreas
VIP der XUG Osnabrück
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

Hi,

bei uns werden die "Dokumente" immer mit dem Standard Programm angezeigt, welches der User auf seinem Rechner (für das bestimme Dokument) installiert hat.
Das können durchaus unterschiedliche Programme sein, je nachdem welche auf dem betreffenden Rechner installiert sind.

Dazu lesen wir aus der Registry das Programm aus welches standardmäßig ein betreffendes Dokument öffnet.
Bsp.
Rechner 1:
.doc -> Winword
.pdf -> PDF ReaderX

Rechner 2:
.doc -> OpenOffice
.pdf -> xxx

Damit sind wir immer auf der sicheren Seite. Und der User sieht ein .doc Dokument immer in seinem Word, sein .pdf wir immer mit PDFReader, etc. angezeigt.

Gruß,
Notloesung
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16516
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Jarek,
im Prinzip reicht es aus, die betreffende Datei per runshell zu starten.
Windows nimmt dann automatisch die mit der Erweiterung verknüpfte Standardanwendung zum Anzeigen.

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

Hallo Martin,

das werde ich ausprobieren.

Notloesung
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Imageview und PDF oder Doc

Beitrag von AUGE_OHR »

hi,
Koverhage hat geschrieben: ich benutze das Sample von Alaska um eingescannte Dokumente
anzuzeigen.
also "Bilder"
Koverhage hat geschrieben: Um die Dokumentenverwaltung komplett zu machen, würde ich auch
gerne DOC, PDF und XLS Dateien darin integrieren.
klar wenn du von den DOC, PDF & XLS Dateien "Bilder" hast :)

wenn es in einem XbpDialog angezeigt werden soll, so geht es nur über activeX.

wenn du "externe" Programme benutzt nehme ich dafür den Registry :

Code: Alles auswählen

...
oReg := XbpReg():NEW(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Extensions)

   IF ! oReg:Status()
       RETURN .F.
   ENDIF

   oReg:ReadBinType("C")

   // Beispiel suche "doc"
   uVal := oReg:getValue('doc')
   uVal := STRTRAN(uVal,'^.doc','')

   // ruft zuletzt bearbeitetes Document auf und plaziert den Cursor
   RunShell( "/mfile1 /mZurückEinfügemarke", uVal, .T. )
...
gruss by OHR
Jimmy
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16516
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Jarek,
ich mache das so (um das störende DOS-Fenster wegzukriegen):

Code: Alles auswählen

ort := "url.dll,FileProtocolHandler " + verz + "\" + datei + ".rtf"
RunShell( ort, 'Rundll32.exe' )
verz enthält Laufwerk und Verzeichnis und datei den Namen der zu öffnenden Datei .

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Koverhage »

Ich glaube hier liegt ein Mißverständnis vor, anhand der Erweiterung kann ich ja feststellen, was für ein Dokument es ist und entsprechend die benötigte
ActiveX Funktion aufrufen (ok für PDF weiß ich das nicht).
In dem Sample IMGVIEW von Alaska (gibt es schon ewig) hier ein Ausscnitt davon:

oDlg1 := XbpDialog():new( AppDesktop(), , aPos, aSize, , .F. )
oDlg1:taskList := .T.
oDlg1:maxButton := .F.
oDlg1:border := XBPDLG_DLGBORDER
oDlg1:title := mess1
oDlg1:close := {|| endestat := .t. }
oDlg1:create()
olast := SetAppWindow( oDlg1 )

drawingArea := oDlg1:drawingArea
drawingArea:setFontCompoundName( FONT_HELV_SMALL )

oDirs := DirSelector():new ( drawingArea, , {12 ,12}, {222,624} )
oDirs:tabStop := .T.
oDirs:startDir := curdrive()+":\"+curdir()+"\" + substr( strzero( m_az, 9 ), 1, 8 ) + "." + substr( strzero( m_az, 9 ), 9, 1 )+"\"
oDirs:create()

oFiles := FileSelector():new( drawingArea, , {246,12}, {336,624} )
oFiles:tabStop := .T.
oFiles:create()

oFiles:setFilesTo( oDirs:curDir(), { "*.JPG", "*.EMF", "*.GIF", "*.BMP", "*.PNG", "*.DOC", "*.RTF", "*.XLS", "*.BMP *.EMF *.GIF *.JPG *.PNG *.PDF *.DOC *.RTF *.XLS" } )

oView := ImageView():new( drawingArea, , {594,96}, {410,540} ):create()

Wird sobald eine Datei angeklickt wird, das entsprechende Bild angezeigt,
aber bei Doc, etc. Dateien soll das ja nicht sein.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi Klaus,

ich habe mir gerade das Beispiel mit Image View (source\samples\apps\imgView) angesehen, das ist wirklich nett, besonders da es die Bilder so schnell anzeigt (XbpStatic).

Dann habe ich mir unter ActiveX den PDF Viewer (source\samples\activeX\acrobat) angesehen. Ich muss dazu sagen, dass ich Acrobat 6.0 Professionell auf dem Rechner habe. Also ich musste etwa 1 Minute warten bevor die PDF beim ersten Aufruf angezeigt wurde. PDF-Dateigröße 75 KB !!!.
Über den InternetExplorer dauert es genausolang.

Ein weiteres Problem liegt darin, dass eine so stark verkleinerte PDF oder Word Datei keinen Sinn macht. Bei diesen Dateitypen wäre es sinnvoller eigene Fenster (mit Runshell etc.) zu starten und dem Anwender die Möglichkeit der Anwendungskonfiguration zu liefern (PDF auf Acrobat Reader, auch wenn Writer installiert ist; DOC auf WordViewer statt auf Word etc.)
Gruß
Hubert
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Koverhage »

Hubert,

ich glaube mit ActiveX habe ich wegen der Geschwingkeit keine Probleme.
Mir geht es primär darum, wie ich erstmal das Verhalten ausschalten kann, bzw. eine andere Routine aufrufen kann, wenn der Anwender auf ein Doc oder XLS oder PDF Dokument klickt.
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16516
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Klaus,
Du brauchst keine Verrenkungen mit ActiveX und Registry machen!
Einfach ein runshell (Beispiel s.o.) und es wird die Standardapplikation zum Anzeigen gestartet...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Koverhage hat geschrieben:Mir geht es primär darum, wie ich erstmal das Verhalten ausschalten kann, bzw. eine andere Routine aufrufen kann, wenn der Anwender auf ein Doc oder XLS oder PDF Dokument klickt.
Ah, klar gefragt, klare Antwort ;-)

Also als erstes sucht man im ImageView Beispiel (ich habe nur diesen Quellcode) nach dem Namen der Listbox, welche die Dateien darstellt: ::fileList

Code: Alles auswählen

METHOD FileSelector:init( oParent, oOwner, aPos, aSize, aPresParam, lVisible )
   ...
   ::fileList         := XbpListBox():new( self )
nun sucht man im Programm wo diesem Object die Callback Blöcke gesetzt werden, die auf Klicken (::fileList:itemMarked) und/oder Doppelklick (::fileList:itemSelected) reagieren sollen.

Etwas tiefer werden wir fündig:

Code: Alles auswählen

METHOD FileSelector:create( oParent, oOwner, aPos, aSize, aPresParam, lVisible )
   ...
   ::fileList:itemMarked   := {|| ::fileMarked() }
   ::fileList:itemSelected := {|| ::fileSelected() }
nun müssen wir suchen wo definiert ist, was die Methoden ::fileMarked() bzw. ::fileSelected() machen.
Besonders tückisch beim Suchen ist jetzt, dass die Authoren des Beispiels die () einfach weggelassen haben, aber wir finden trotzdem:

Code: Alles auswählen

 * Benutzerdefiniertes Ereignis "Datei ist markiert" plus Dateinamen senden
METHOD FileSelector:fileMarked
   LOCAL aItems := ::fileList:getData()
   IF ! Empty( aItems ) .AND. ! Empty( ::aFiles )
      PostAppEvent( xbeFS_FileMarked, ::cDir + "" + ::aFiles[ aItems[1] ] )
   ENDIF
RETURN self
 * Benutzerdefiniertes Ereignis "Datei ist gewählt" plus Dateinamen senden
METHOD FileSelector:fileSelected
   LOCAL aItems := ::fileList:getData()
   IF ! Empty( aItems ) .AND. ! Empty( ::aFiles )
      PostAppEvent( xbeFS_FileSelected, ::cDir + "" + ::aFiles[ aItems[1] ] )
   ENDIF
RETURN self
Also es ginge auch einfacher, indem man hier einfach die Aufrufe eingesetzt hätte, aber der Autor definiert benutzerdefinierte Events.
Nun ist ja klar wo wir danach suchen müssen ... in der Eventloop, also meist am Ende von MAIN.

Code: Alles auswählen

   DO WHILE .T.
      nEvent := AppEvent( @mp1, @mp2, @oXbp )
      IF nEvent == xbeDS_DirChanged
         oFiles:setFilesTo( mp1 )
      ELSEIF nEvent == xbeFS_FileMarked
         oView:load( mp1 )
         oView:display()
      ELSE
          oXbp:handleEvent( nEvent, mp1, mp2 )
      ENDIF
   ENDDO
genau in dieser Zeile wird abgefragt ob ein Event 'Markiert' entstanden ist und danach was zu geschehen hat. Man könnte eine kleine do case Dateityp Verschachtelung einbauen.

Code: Alles auswählen

      ELSEIF nEvent == xbeFS_FileMarked
         oView:load( mp1 )
         oView:display()
Und wir sehen, dass ein doppelklick garnichts bewirkt, auch wenn es anders aussieht ! Denn hier ist nichts geregelt und der Event wird an Handleevent abgegeben, was für diesen sicher nichts vorsieht.

Das ist ein gutes Beispiel für das Vorgehen bei GUI Applikationen.
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Beitrag von AUGE_OHR »

hi,
brandelh hat geschrieben:
Koverhage hat geschrieben:Mir geht es primär darum, wie ich erstmal das Verhalten ausschalten kann, bzw. eine andere Routine aufrufen kann, wenn der Anwender auf ein Doc oder XLS oder PDF Dokument klickt.
Und wir sehen, dass ein doppelklick garnichts bewirkt, auch wenn es anders aussieht ! Denn hier ist nichts geregelt und der Event wird an Handleevent abgegeben, was für diesen sicher nichts vorsieht.
vorweg : Sehr schöne Erklärung !

Ich versuche mal an der Stelle weiter zu machen, den nun kommen ja
die nächsten Probleme ...

Wenn man also die Fileliste um die Extension *.DOC *.XLS *.PDF erweitert
hat kann man die zwar in der Combox "sehen" aber weder die "Vorschau"
noch der "VollBild" Button machen irgendwas. Das man keine "Vorschau"
hat ist ja noch akzeptabel, aber vielmehr als den "VollBild" Button gibt
es ja nicht (ausser Ende). Also mal nachschauen was "VollBild" macht.

Code: Alles auswählen

PROCEDURE FullView( cFile )
...
  /*
   * Es werden nur Bitmap und Metadateien unterstützt
   */
   IF cFile <> NIL            .AND. ;
     ( ".BMP" $ Upper( cFile ) .OR. ;
       ".EMF" $ Upper( cFile ) .OR. ;
       ".GIF" $ Upper( cFile ) .OR. ;
       ".JPG" $ Upper( cFile ) .OR. ;       
       ".PNG" $ Upper( cFile ) .OR. ;
       ".MET" $ Upper( cFile )      )
...  
   ENDIF
klar also warum nicht passiert. Nun kann man genau hier das Programm
"aufbohren" wenn man statt dem ENDIF ein ELSEIF benutzt und
damit die *.DOC *.XLS *.PDF Routinen starten.
brandelh hat geschrieben: Das ist ein gutes Beispiel für das Vorgehen bei GUI Applikationen.
wenn man es verstanden hat : JA :)

aber als ich es das erste Mal gesehen habe fand ich das doch ziemlich
"fett" als Demo. TreeView, Listbox und ImageView in einem Beispiel
sind "am Anfang" für jemanden der von Cl*pper kommt kaum zu durch-
schaun und hätten als "Einzel" Demo es vielleicht einfacher gemacht.
brandelh hat geschrieben: Also es ginge auch einfacher, indem man hier einfach die Aufrufe
eingesetzt hätte, aber der Autor definiert benutzerdefinierte Events.
DAS finde ich nun ist das eigendliche interessanteste an dem ganzen
Demo. Bis dahin hab ich unter Cl*pper nur ein Inkey() als "Event"
gehabt was aber "nur" auf ein "Fenster" reagieren konnte.

Als ich 2004 die v1.9beta in die Hände bekam und mein Mediaplayer
Project begann hatte ich gleich am Anfang das Problem von 7 "Events"
"Play","Stop","Pause","Fastforward","Fastreward","Next" und "Previerios".

In der ersten Version hatte ich die "Buttons" noch auf dem MainDialog,
aber schon bald drängte sich der Wunsch auf die "Buttons" als seperates
"Fenster" laufen zu lassen, aber wie dann noch die "Befehle" der "Buttons"
an das "Player Fenster" leiten ?

Da viel mir nun wieder das ImageView Demo an wo der Author UserDef.
"Events" verwendet hat. Nun sendet das Programm praktisch nur noch
"Events" und das aus mehreren Thread um das aktiveX Modul zu steuern.

Code: Alles auswählen

...
      // play next in "Playlist"
      //
   CASE nKey == aHIDkeys[HID_PLAYNX]            // PlayNext
      PostAppEvent(xbeE_Next)
      setAppFocus(oMainDlg)
      //
      // play previerious in "Playlist"
      //
   CASE nKey == aHIDkeys[HID_PLAYPR]            // PlayPrev
      PostAppEvent(xbeE_Prev   )
      setAppFocus(oMainDlg)
      //
      // "rewind"
      //
   CASE nKey == aHIDkeys[HID_REWIND]            // WM9Rewind
      PostAppEvent(xbeE_Rewind )
      //
      // "stop"
      //
   CASE nKey == aHIDkeys[HID_STOP]              // WM9Stop
      PostAppEvent(xbeE_Stop   )
      //
      // "play"
      //
   CASE nKey == aHIDkeys[HID_PLAY]              // WM9Play
      IF aoChild[CH_WMP]:PlayState = wmppsPlaying
         PostAppEvent(xbeE_Pause)
      ELSE
         PostAppEvent(xbeE_Play   )
         PostAppEvent(xbeP_Resize,oMainDlg:CurrentSize(),oMainDlg:CurrentSize(),oMainDlg)
      ENDIF
   CASE nKey == aHIDkeys[HID_PAUSE]             // WM9Pause
      IF aoChild[CH_WMP]:PlayState >= wmppsPlaying .AND. aoChild[CH_WMP]:PlayState <= wmppsScanReverse
         PostAppEvent(xbeE_Pause)
      ELSE
         IF aoChild[CH_WMP]:PlayState=wmppsPaused
            PostAppEvent(xbeE_Play)
            PostAppEvent(xbeP_Resize,oMainDlg:CurrentSize(),oMainDlg:CurrentSize(),oMainDlg)
         ENDIF
      ENDIF
      setAppFocus(oMainDlg)
   CASE nKey == aHIDkeys[HID_FASTFO]            // WM9Forward
      PostAppEvent(xbeE_Forward)
...
Die "Belegung" der "Buttons" ist hier übrigens in einem Array hinterlegt
sodas der User selbst definieren kann welche "Taste" welchem "Button"
zugeordnet werden soll. Damit lässt sich auch eine HID "Fernbedienung"
auf die "Buttons" definieren und man kann das ganze vom Sofa aus
steuern.

aber zurück zum Thema UserDef. "Events" :

Da man nun die "Events" von "überall" an "jeden" senden kann bin ich
nicht mehr "gezwungen" sofort "vor Ort" eine Aktions auszuführen.

Vielmehr kann ich den "Event" z.b. an den "Player" schicken und
"ausführen" lassen , während ich weiter in meiner "PlayList" suche.

DAS macht MDI auch erst interessant, das man "Befehle" verschickt
statt die "selbst auszuführen" ... :)

gruss by OHR
Jimmy
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2935
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Beitrag von Wolfgang Ciriack »

@Klaus,
ich habe eine Vorschau für JPG- und PDF-Dateien mit eXPress++ implementiert, wenn du interessiert bist, schicke mir einfach eine Mail.
Viele Grüße
Wolfgang
Antworten