Deutsch
Forum

Single-Instance Commandline ImageViewer mit GDI+

 

Edelpfuscher
moin moin!
es schreibt und grüßt stefan, 44 jahre, bits'n'bytes-verwurschtler aus hamburg.

brauche im job einen bildbetrachter mit den anforderungen: läuft unter den meisten win-versionen, fix, tauglich für alle gängigen formate, höhe/breite einpassen, zoomen, scrollen, fokus an aufrufende app zurückgeben, standalone, single-instance ... und zwar ausschließlich als kommandozeilen-tool.
(das ginge theoretisch auch alles mit Irfan, allerdings ist der viel zu mächtig. es gibt ja fast keinen buchstaben, der bei ihm nicht als - bisweilen fataler - shortcut herhalten muss.)

nachdem das halbe inet durchforstet hab und alle downloads vergeblich ausgetestet waren, stand fest: selbermachen. irgendwo fand sich dann auch in den gesammelten werken die eingestaubte xprofan-cd (version 8.0) und das grundgerüst war erstaunlich schnell zusammen(-geklaut, vielen dank an die gemeinde!), so weit - so gut.

probs:
- ohne 'SetAutoPaint 0' war gar nix mit neuzeichnen - mit flackert's recht ordentlich
- die geschichte mit der einmaligen instanz will einfach nicht richtig funzen

den fred 'Doppelstart Instanzen Mehrere Programmstarts Verhindern' habe ich hoch und runter durchgekaut - danke nochmals an die spezialisten! außer dem ansatz mit FindWindow (im beispiel auskommentiert, weil zu langsam) flogen mir die speicherverletzungen nur so um die ohren.

favorisieren würde ich ein verhalten: alte instanz(en) bemerken und beenden.

auf weitere tipps, anregungen, beispiele freue ich mich schon,
danke und horrido!

6 kB
Kurzbeschreibung: XProfanCode (8.0)
Hochgeladen:05.11.2012
Ladeanzahl174
Herunterladen
 
05.11.2012  
 



Grüße!

Es gibt nicht wirklich eine immer funktionierende Möglichkeit, einen solchen

Doppelprogrammstart Windows-Versionen-übergreifend 100%ig zuverlässig

zu verhindern. Du kannst user32::FindWindow benutzen aber auch hierauf kannst

Du Dich aus verschiedenen Gründen nicht 100%ig verlassen. Vielleicht ist es

noch relativ sicher per TimerProc die regelmäßg (z.B. einmal pro Sekunde) per

FindWindow findet und ggf. eine Beenden-Nachricht sendet. Mutexe zu

Programmstart oder Speicherdateien sind nicht "sicherer" da in neueren Windows-

Versionen von Prozess zu Prozess unterschiedliche Zugriffsrechte nicht immer

vorhanden sein müssen. SetAutoPaint 0 zeichnet nichts neu, darum ja 0.

Eine Window-APP soll das Fenster selbst neu zeichnen wenn es die Nachricht

dazu bekommt. Du könntest hierzu also mit SubClassing arbeiten wenn Du nicht

auf dem hWnd zeichnen möchtest. Ich würde bei Deinem Beispiel wohl einfach auf

dem hWnd zeichnen und %hDC2 sowie %HDC gleichermaßen beschreiben sodass

XProfan sich selbst um das Neuzeichnen des %hWnd kümmern kann.
 
06.11.2012  
 




Edelpfuscher
besten dank!

und: schade, schade - die schlechten nachrichten hatte ich befürchtet. es kursieren ja diverse 'single instance dlls' - daher entstand die schwache hoffnung, dass es irgendwie stabiler und allgemeingültiger zu machen wäre. (es muss ja bitte nicht gleich c# sein...)

das aufrufende HTA jongliert schon mit reichlich anderem kram herum und sollte von solchen aufgaben der 'instanz-kontrolle' eigentlich verschont bleiben. Timer wären wohl in jedem Fall zu langsam, da z.b. eine 180°-drehung ggf. nur die zeitspanne eines doppelklicks ausmacht, und dabei evtl. schon zwei aufrufe absetzt.

immerhin: den zusammenhang mit '%hDC2 sowie %HDC' hab ich ein paar male verfolgt und doch nicht wirklich kapiert. muss ich wohl nochmal aufgreifen... :o)

horrido!
 
06.11.2012  
 




E.T.

...
favorisieren würde ich ein verhalten: alte instanz(en) bemerken und beenden
...


Ich denke, da ist wohl die FindWindow-Variante die beste. Ich löse das bis jetzt immer so (für bessere Varianten bin ich gern lernfähig), und dies hat bis Win 7 bis jetzt auch noch keine Probleme verursacht.
Natürlich sollte das eigene Progg-Fenster nicht gerade "Explorer"  oder so benannt werden...

Mit dieser Verfahrensweise ist es mir auch noch nie passiert, das mehrere Instanzen das Proggs am werkeln waren, weil ja die einzig laufende bei Neustart des Proggs gekillt  wird. Und wer auf Nummer sicher gehen will, kann ja nach dem "killen"  einer vorhandenen Instanz die Suche noch 3x wiederholen
 
XProfan X2
Grüße aus Sachsen... Mario
WinXP, Win7 (64 Bit),Win8(.1),Win10, Win 11, Profan 6 - X4, XPSE, und 'nen schwarzes, blinkendes Dingens, wo ich das alles reinschütte...
06.11.2012  
 




Jörg
Sellmeyer
Ich hab keine Lösung für das Problem aber eine Möglichkeit, wie die Findwindow-Lösung schneller werden könnte.
Anstatt das zuerst aufgerufene Programm zu beenden und das neue Bild durch das zweite Programm anzeigen zu lassen, kann das zweite Programm nach erfolgtem Check auf Vorhandensein des ersten, diesem einfach das neue Bild als Parameter übergeben und sich dann wieder selber beenden. Das erste Programm stellt dann das Bild in gewünschter Größe dar. Da muss dann nicht nochmal die Programmoberfläche aufgebaut werden, während parallel das este Programm geschlossen wird.
 
Windows XP SP2 XProfan X4
... und hier mal was ganz anderes als Profan ...
06.11.2012  
 




Edelpfuscher
moin und danke nochmals.

die suche nach vorhanden instanzen wird ja nicht dreimal wiederholt, sondern so oft wie nötig:

While (@FindWindow("iv") > 0)
MyHandle& = @FindWindow("iv")
PostMessage(MyHandle&, $10, 0, 0, 0)
Wend

genau das führt zum problem: zwischen dieser schleife und dem aufspannen des neuen, 'findbaren' fensters mit titel vergeht ggf. so viel zeit, dass der doppelstart eben doch nicht sicher vermieden werden kann. das 'findbare' Window füher zu setzen (und natürlich vom kill auszuschließen), führt zu einer augenkrebs-verdächtigen flackerei.

könnte evtl. eine 'kill-message' ($10, $12, etc.) schneller sein als eine andere?! oder liegt der flaschenhals, wie zu vermuten wäre, doch bei FindWindow selbst?

das senden der parameter von instanz 2 an nr. 1 wäre sicher richtig knorke, gerade auch bezügl. des flackerns. aber wie bekomme ich auf möglichst vielen windoof-versionen die parameter heil rübergeschaufelt? gibt's da etwas 'halbwegs' sicheres?

horrido!
 
06.11.2012  
 



Wie funktioniert dies hier bei Dir?

Download
KompilierenMarkierenSeparieren
 {$cleq}
const appTitle="myApp"
const checkVersionMsg=wm_user+1234
//
windowstyle 1 | 2 | 4 | 8 | 16 | 512
windowtitle appTitle
cls
userMessages wm_close,checkVersionMsg
// Adresse nativer Proc beziehen und Opcode abholen
long myNativeTimerProcOpcode=globalAlloc(gPTR,1024)
rtlMoveMemory(myNativeTimerProcOpcode,procAddr(myNativeTimerProc),1024)
//Opcode patchen und Startzeit nativ hinterlegen
long myNativeTimerProcOpcode&,7=getTickCount
// nativen Timer erzeugen ud auf Opcode lenken
~setTimer(0,0,333,myNativeTimerProcOpcode)

do {

    waitinput

    select %uMessage

        caseof wm_close : break

        caseof checkVersionMsg

        case &ulParam<long(myNativeTimerProcOpcode,7) : break

    endSelect

}

end

nProc myNativeTimerProc(long wnd,uMsg,idEvent,dwTime){

    push $FFFFFF
    pop eax
    long myTime=eax
    long chk=findWindowX(appTitle)
    //
    case chk : sendMessage(chk,checkVersionMsg,0,myTime)

}

// https://xprofan.com/intl/de/quelltexte/findwindow-findwindowx-nproc-xprofan/

nProc findWindowX(string s){

    case s=="" : return 0
    long lst=dim(16)
    long lst&,0=0,addr(s),dim(512),len(s)
    enumWindows(procAddr(findWindowX.enumProc),lst)
    long h=long(lst,0)
    dispose(long(lst,8))
    dispose(lst)
    return h

}

nProc findWindowX.enumProc(long wnd,lst){

    PushAll

    if wnd==hWnd {

        popAll
        return true

    }

    long 	r=getWindowTextLength(wnd),\
    l=long(lst,12)

    if r<l {

        PopAll
        return true

    }

    ifnot r==getWindowText(wnd,long(lst,8),511) {

        PopAll
        return true

    }

    if char(long(lst,4),0,l)==char(long(lst,8),0,l) {

        long lst&,0=wnd
        PopAll
        return false

    }

    PopAll
    return true

}


Damit der Quelltext bei Dir läuft musst XProfan mit XPSE pimpen: [...]  -

aber kannst ja erstmal die Exe testen.

Bei diesem Code bleibt die älteste Instanz erhalten.

Kann auch leicht umgestellt werden auf: Ältere beenden & Neuere erhalten

Auf jeden Fall verursacht dieser Code keine Systemlast und arbeitet quasi im

Hintergrund passiv und delegiert nur das Programmbeenden. Kannst ja mal

im Explorer auf der Test.Exe mit der Entertaste draufbleiben sodass schön

viele Instanzen erzeugt werden - kann man zusehen wie sie alle wieder verschwinden/

zuverlässig abgearbeitet werden und nur die Erste übrig bleibt.

1.167 kB
Hochgeladen:06.11.2012
Ladeanzahl115
Herunterladen
 
06.11.2012  
 




Edelpfuscher
sehr cool, danke!

rennt wie gewünscht, jetzt muss ich nur noch doch den code durchsteigen...
und das wird, wie's aussieht, eine ganze weile dauern... ;o)

rückmeldung folgt...
 
06.11.2012  
 



Wenns erstmal grundsätzlich so funzt wie von Dir gewünscht dann einfach noch fix

durchgeben was noch zu erledigen ist da ich das dann fix mit einbauen würde.

Beispielsweise müsste das "neuere" Fenster garnicht erst erscheinen wenn bereits

eins vorhanden ist. Das hilfreiche an diesem Code ist dass das XProfan-Programm

selbst eigentlich nichts zu tun hat ausser zu schauen ob eine UserMessage

checkVersionMsg vorliegt und es sich beenden sollte wenn &ulParam <

long(myNativeTimerProcOpcode,7).
 
06.11.2012  
 




Edelpfuscher
die versprochene rückmeldung:

mein wissensrückstand bezügl. XPSE und aktuelleren Profanversionen ist offensichtlich viel zu groß, um in angemessener zeit zu einem brauchbaren ergebnis zu kommen.

kümmere mich also mittlerweile an anderer stelle um das töten überzähliger instanzen und lebe mit der krücke (die soweit zufriedenstellend und stabil läuft).

nochmals vielen dank für die tipps und anregungen.
wann ich dazu kommen werde, mein profanes halbwissen zu vertiefen, bleibt leider ungewiss.

horrido!
 
15.11.2012  
 



Antworten


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

6.879 Betrachtungen

Unbenanntvor 0 min.
Walter31.03.2016
Ernst25.04.2014
Peter Max Müller20.09.2013
trusel01.09.2013
Mehr...

Themeninformationen



Admins  |  AGB  |  Anwendungen  |  Autoren  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Händlerportal  |  Impressum  |  Mart  |  Schnittstellen  |  SDK  |  Services  |  Spiele  |  Suche  |  Support

Ein Projekt aller XProfaner, die es gibt!


Mein XProfan
Private Nachrichten
Eigenes Ablageforum
Themen-Merkliste
Eigene Beiträge
Eigene Themen
Zwischenablage
Abmelden
 Deutsch English Français Español Italia
Übersetzungen

Datenschutz


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie