| |
|
|
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! |
|
|
| |
|
|
|
| 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. |
|
|
| |
|
|
|
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! |
|
|
| |
|
|
|
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 X2Grüß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! |
|
|
| |
|
|
|
| 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. |
|
|
| |
|
|
|
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... |
|
|
| |
|
|
|
| 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). |
|
|
| |
|
|
|
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! |
|
|
| |
|
|