Notice: This forum has been recovered from an old backup, so some content, links, and dates may be outdated. The forum is currently read-only while we restore sign-in and registration functionality. Details
If you find this forum valuable and would like to help keep it online, donations to help cover hosting and domain costs are greatly appreciated, but never expected. You can support the forum through Buy Me a Coffee or Ko-fi. Thank you for helping preserve the EventGhost community.
If you find this forum valuable and would like to help keep it online, donations to help cover hosting and domain costs are greatly appreciated, but never expected. You can support the forum through Buy Me a Coffee or Ko-fi. Thank you for helping preserve the EventGhost community.
Registry Plugin (war: Dialog Layout)
- Bitmonster
- Site Admin
- Posts: 2239
- Joined: Mon Feb 06, 2006 10:28 pm
Ich habe das Plugin jetzt noch nicht in allen Details ausprobiert, aber mal so meine ersten Gedanken:
1. Das mit den Labels ist schon richtig so, denke ich. Man sollte nur vielleicht zu lange Labels abk├╝rzen. Also das man aus z.B. aus
HKEY_CURRENT_USER\SOFTWARE\NVIDIA Corporation\Global\nView\WindowManagement\rtvscan\Exceptions\#32770
etwas macht wie
HKCU\...\Exceptions\#32770
damit es ├╝bersichtlich bleibt. Ist nat├╝rlich auch nicht perfekt aber vielleicht doch etwas besser.
2. Dass ein neuer Dialog immer mit HKCU/Software aufgeht, dieses aber nicht im Baum selektiert ist, verwirrt etwas. Dein Code ist ja schon daf├╝r ausgelegt, den Key zu finden und anzuzeigen. Bei neuen Aktionen macht er es aber anscheinend nicht. Du kannst auch noch einen Trick verwenden:
Wenn du das Ergebnis der letzten Selektierung in die Plugin-Instanz schreibst, dann kann man das dazu verwenden beim Erstellen einer neuen Action gleich die letzte Selektierung als Vorgabe zu verwenden.
Man k├Ânnte die letzte Selektierung sogar in die EG-Konfiguration schreiben, dann funktioniert das sogar ├╝ber mehrere Sessions hinweg. Regedit macht das ja auch so.
3. Im Logger etwas aus der Konfiguration anzeigen zu lassen ist eigentlich nicht sch├Ân. Beim FindWindow habe ich das zwar auch gemacht, aber das soll auch noch rausfliegen. Zu oft verdeckt der Konfig-Dialog den Logger und dann kriegt der User das gar nicht mit.
4. Die Drop-Down-Box für den Hauptzweig würde ich vielleicht wieder rauswerfen. Tut sicher weh, wenn man sowas schon eingebaut hat, aber ich denke dass ist praktischer für den User, wenn er den Suchpfad direkt vollständig pasten kann. Oft kommen die Leute ja auf die Idee mal schnell sowas zu verwenden, wenn es irgendwo im Netz steht und da steht dann ja auch immer der volle Pfad in einem Stück.
Man m├╝sste dann nur soviel Intelligenz in den Code legen, dass er z.B. sowohl HKCU und HKEY_CURRENT_USER als das Gleiche erkennt.
Na ja, aber den Plugin Developer Titel kriegste schon mal.
1. Das mit den Labels ist schon richtig so, denke ich. Man sollte nur vielleicht zu lange Labels abk├╝rzen. Also das man aus z.B. aus
HKEY_CURRENT_USER\SOFTWARE\NVIDIA Corporation\Global\nView\WindowManagement\rtvscan\Exceptions\#32770
etwas macht wie
HKCU\...\Exceptions\#32770
damit es ├╝bersichtlich bleibt. Ist nat├╝rlich auch nicht perfekt aber vielleicht doch etwas besser.
2. Dass ein neuer Dialog immer mit HKCU/Software aufgeht, dieses aber nicht im Baum selektiert ist, verwirrt etwas. Dein Code ist ja schon daf├╝r ausgelegt, den Key zu finden und anzuzeigen. Bei neuen Aktionen macht er es aber anscheinend nicht. Du kannst auch noch einen Trick verwenden:
Wenn du das Ergebnis der letzten Selektierung in die Plugin-Instanz schreibst, dann kann man das dazu verwenden beim Erstellen einer neuen Action gleich die letzte Selektierung als Vorgabe zu verwenden.
Man k├Ânnte die letzte Selektierung sogar in die EG-Konfiguration schreiben, dann funktioniert das sogar ├╝ber mehrere Sessions hinweg. Regedit macht das ja auch so.
3. Im Logger etwas aus der Konfiguration anzeigen zu lassen ist eigentlich nicht sch├Ân. Beim FindWindow habe ich das zwar auch gemacht, aber das soll auch noch rausfliegen. Zu oft verdeckt der Konfig-Dialog den Logger und dann kriegt der User das gar nicht mit.
4. Die Drop-Down-Box für den Hauptzweig würde ich vielleicht wieder rauswerfen. Tut sicher weh, wenn man sowas schon eingebaut hat, aber ich denke dass ist praktischer für den User, wenn er den Suchpfad direkt vollständig pasten kann. Oft kommen die Leute ja auf die Idee mal schnell sowas zu verwenden, wenn es irgendwo im Netz steht und da steht dann ja auch immer der volle Pfad in einem Stück.
Man m├╝sste dann nur soviel Intelligenz in den Code legen, dass er z.B. sowohl HKCU und HKEY_CURRENT_USER als das Gleiche erkennt.
Na ja, aber den Plugin Developer Titel kriegste schon mal.
1) Kann ich noch mal ändern. Nachdem Schema ist es ja auch noch recht einfach. Wie geht das denn mit dem Platzhalter in den Labeltexten, wie es sonst benutzt wird?
2) Bei mir ist HKCU\Software dann auch im Baum selektiert?!?!
Ins PlugIn schreiben d├╝rfte ich noch hinkriegen, aber wie das mit der Instanz geht ist auch noch so eine Sache.
Bei der Configsache kann ich auch gleich noch eine Sache ansprechen. Eigentlich mag ich es ja nicht, wenn Programme etwas in ihr eigenes Verzeichnis schreiben. Das geh├Ârt ja eigentlich eher ins Userverzeichnis. Bei eingeschr├ñnkten Benutzern muss man sowas erst m├╝hsam rausfinden und die Dateisystemrechte entsprechend ├ñndern.
3) Ich w├╝rde es ja gerne reichschreiben, aber mir ist auch nach einigem Nachdemken keine sinnvolle Positionierung/Darstellung eingefallen.
4) Kann ich mal schauen So schwer kann das ja auch nicht sein.
Gibt es irgendwo schon ein Beispiel einer Validierung vorm Bestätigen?
2) Bei mir ist HKCU\Software dann auch im Baum selektiert?!?!
Ins PlugIn schreiben d├╝rfte ich noch hinkriegen, aber wie das mit der Instanz geht ist auch noch so eine Sache.
Bei der Configsache kann ich auch gleich noch eine Sache ansprechen. Eigentlich mag ich es ja nicht, wenn Programme etwas in ihr eigenes Verzeichnis schreiben. Das geh├Ârt ja eigentlich eher ins Userverzeichnis. Bei eingeschr├ñnkten Benutzern muss man sowas erst m├╝hsam rausfinden und die Dateisystemrechte entsprechend ├ñndern.
3) Ich w├╝rde es ja gerne reichschreiben, aber mir ist auch nach einigem Nachdemken keine sinnvolle Positionierung/Darstellung eingefallen.
4) Kann ich mal schauen So schwer kann das ja auch nicht sein.
Gibt es irgendwo schon ein Beispiel einer Validierung vorm Bestätigen?
- Bitmonster
- Site Admin
- Posts: 2239
- Joined: Mon Feb 06, 2006 10:28 pm
1. Einfach ├╝ber eg.ParseString schicken in der __call__ Methode. Also sowas am Anfang machen:
pathname = eg.ParseString(pathname)
2. Bei mir nicht. Kann es sein, dass die Suche case-sensitive ist und es bei dir tatsächlich "Software" heißt? Bei mir ist es nämlich "SOFTWARE". Schlüsselfpfade sind übrigens allgemein case-insensitive.
Was meinst du mit "aber wie das mit der Instanz geht ist auch noch so eine Sache"?
Das Configfile im Programmverzeichnis ist wirklich eine schlechte L├Âsung. Werde ich mal ├ñndern. Der urspr├╝ngliche Gedanke war, dass der User dann sp├ñtestens beim L├Âschen des Programmordners sicher sein kann, dass nichts mehr von EG ├╝ber ist.
4. Gute Frage. Muss ich mal schauen. Bisher waren es immer Controls die selber validieren und ich dann ggfs. den OK-Button disabled habe.
pathname = eg.ParseString(pathname)
2. Bei mir nicht. Kann es sein, dass die Suche case-sensitive ist und es bei dir tatsächlich "Software" heißt? Bei mir ist es nämlich "SOFTWARE". Schlüsselfpfade sind übrigens allgemein case-insensitive.
Was meinst du mit "aber wie das mit der Instanz geht ist auch noch so eine Sache"?
Das Configfile im Programmverzeichnis ist wirklich eine schlechte L├Âsung. Werde ich mal ├ñndern. Der urspr├╝ngliche Gedanke war, dass der User dann sp├ñtestens beim L├Âschen des Programmordners sicher sein kann, dass nichts mehr von EG ├╝ber ist.
4. Gute Frage. Muss ich mal schauen. Bisher waren es immer Controls die selber validieren und ich dann ggfs. den OK-Button disabled habe.
1) Das versteh ich jetzt nicht ganz. Ich meinte die Syntax wie es z.B. beim TriggerEvent.getLabel() vorkommt. Da heißt es und in labelWithTime steht dann Diese Form hab ich zwar schon an einigen anderen Stellen gesehen, aber ich weiß echt nicht wie die funktioniert.
2) Jup bei mir heißt das "Software". Werde ich noch anpassen.
3) mit dem Kauderwelsch wollte ich nachfragen, wie man Werte so setzt, dass EG sie im Configfile abspeichert und beim Starten wiederherstellt.
Code: Select all
return self.text.labelWithTime % (eventString, waitTime)Code: Select all
Trigger event "%s" after %.2f seconds2) Jup bei mir heißt das "Software". Werde ich noch anpassen.
3) mit dem Kauderwelsch wollte ich nachfragen, wie man Werte so setzt, dass EG sie im Configfile abspeichert und beim Starten wiederherstellt.
- Bitmonster
- Site Admin
- Posts: 2239
- Joined: Mon Feb 06, 2006 10:28 pm
1. Achso, ich dachte du meinst die Variablen-Ersetzung mit dem Geschweifte-Klammern-Syntax, den EG an vielen Stellen hat.
Was du meinst steht hier: http://docs.python.org/lib/typesseq-strings.html
3. Schreibe ich bei Gelegenheit mal ein HowTo zu. Ich hatte die Funktion jetzt gerade aus den Plugins und Actions rausgenommen, weil sie praktisch nur von zwei Aktionen benutzt wird und ich lieber die Klassen ├╝bersichtlich halten wollte.
Was du meinst steht hier: http://docs.python.org/lib/typesseq-strings.html
3. Schreibe ich bei Gelegenheit mal ein HowTo zu. Ich hatte die Funktion jetzt gerade aus den Plugins und Actions rausgenommen, weil sie praktisch nur von zwei Aktionen benutzt wird und ich lieber die Klassen ├╝bersichtlich halten wollte.
- Bitmonster
- Site Admin
- Posts: 2239
- Joined: Mon Feb 06, 2006 10:28 pm
3.)
Machen wir doch mal die Kurzform:
Zuerst brauchst du eine Klasse mit deinen Default-Werten, also z.B.
Dann rufst du in deiner Plugin __init__ die Funktion eg.GetConfig() auf:
In self.config.lastKey steht dann der Wert. Beim ersten Mal "HKCU\Software".
Ver├ñnderst du nun self.config, dann wird das automatisch beim Beenden von EG gesichert und beim n├ñchsten eg.GetConfig() wieder hervorgeholt. "plugins.Registry" ergibt sich aus dem Klassennamen deines Plugins. Das ist nat├╝rlich nicht absolut sicher, weil ein anderes Plugin auf die Idee kommen k├Ânnte genauso zu hei├ƒen. Zur Zeit geht das aber, weil wir ja noch die ├£bersicht haben.
Machen wir doch mal die Kurzform:
Zuerst brauchst du eine Klasse mit deinen Default-Werten, also z.B.
Code: Select all
class Defaults:
lastKey = "HKCU\Software"
Code: Select all
self.config = eg.GetConfig("plugins.Registry", Defaults)Ver├ñnderst du nun self.config, dann wird das automatisch beim Beenden von EG gesichert und beim n├ñchsten eg.GetConfig() wieder hervorgeholt. "plugins.Registry" ergibt sich aus dem Klassennamen deines Plugins. Das ist nat├╝rlich nicht absolut sicher, weil ein anderes Plugin auf die Idee kommen k├Ânnte genauso zu hei├ƒen. Zur Zeit geht das aber, weil wir ja noch die ├£bersicht haben.
Last edited by Bitmonster on Thu Aug 24, 2006 1:20 pm, edited 1 time in total.
Hier mal ein upgedater Code. Bislang noch ohne das Abspeichern der Einstellungen im globalen. Grade schon verr├╝ckt worden, weil ich kein event.skip() eingebaut hatte und deshalb immer nur ein Handler aufgerufen wurde. Und danach gabs Probleme, weil die Handler in der "falschen" Reihenfolge aufgerufen wurde und ich immer den alten Wert ausgelesen hab:oops:
Daf├╝r gibt es jetzt auch die K├╝rzung der Labels und wenn man f├╝r den Subkey einen Wert einf├╝gt, der den passenden Anfang hat wird die Auswahlbox gesetzt und der Text entsprechend verk├╝rzt. Das d├╝rfte f├╝r unbedarftes C&P reichen
Daf├╝r gibt es jetzt auch die K├╝rzung der Labels und wenn man f├╝r den Subkey einen Wert einf├╝gt, der den passenden Anfang hat wird die Auswahlbox gesetzt und der Text entsprechend verk├╝rzt. Das d├╝rfte f├╝r unbedarftes C&P reichen
Code: Select all
[Source Code entfernt, da neuere Version weiter unten verf├╝gbar]- Bitmonster
- Site Admin
- Posts: 2239
- Joined: Mon Feb 06, 2006 10:28 pm
Was mir noch so aufgefallen ist:
Das geht nicht. Die Text-Klasse wird nur f├╝r die Plugin-Klasse ├╝bersetzt und dann u.U. auf die Action-Klassen verteilt. Wenn du f├╝r das Fenster darauf zugreifen willst, dann musst du die self.text Referenz des Plugins ├╝bergeben. Z.B. als Parameter der RegistryChooser.__init__.
Die hast du unter dem Plugin angeordnet. Wäre aber doch ratsamer es unter die Actions anzuordnen, damit die in GetLabel() einfach nur auf self.text zugreifen müssen, statt auf self.plugin.text.
regKeys und regTypes brauchen schätzungsweise nicht in der Text-Klasse stehen, weil die wohl nicht übersetzt werden müssen. Zudem hat ein Übersetzer keinen Zugriff auf _winreg in seinem Language-File und somit würde das so sowieso nicht klappen.
Den import mag ich gar nicht. Versuch mal den wegzulassen und alle wx-Sachen immer ├╝ber den wx.XXX Weg anzusprechen, statt ├╝ber wxXXX.
Code: Select all
class RegistryChooser(wx.Window):
text = Text
Code: Select all
changeActions = ("create or change", "change if exists only", "delete")
changeActionLabel = ('Change "%s" to %s', 'Change "%s" to %s if exists only', 'Delete "%s"')
queryActions = ("check if exists", "return as result", "compare to")
queryActionLabel = ('Check if "%s" exists', 'Return "%s" as result', 'Compare "%s" with %s')
regKeys und regTypes brauchen schätzungsweise nicht in der Text-Klasse stehen, weil die wohl nicht übersetzt werden müssen. Zudem hat ein Übersetzer keinen Zugriff auf _winreg in seinem Language-File und somit würde das so sowieso nicht klappen.
Code: Select all
from wxPython.wx import * neuer Versuch.
Ich suche für etwas anderes noch eine Eingabekomponente für Freitext, wo man aber per Dropdownliste auch Vorgaben auswählen kann. Gibt es doch bestimmt schon fertig, ich weiß nur nicht wie das heißt.
Ich suche für etwas anderes noch eine Eingabekomponente für Freitext, wo man aber per Dropdownliste auch Vorgaben auswählen kann. Gibt es doch bestimmt schon fertig, ich weiß nur nicht wie das heißt.
Code: Select all
import eg
import wx
import _winreg
import binascii
from eg.cFunctions import RegEnumKeysAndValues
class Text:
noKeyError = "No key given"
noSubkeyError = "No subkey given"
noTypeError = "No type given"
noNewValueError = "No new value given"
noValueNameError = "No value name given"
keyOpenError = "Error opening registry key"
valueChangeError = "Error while modifying value"
defaultText = "(Default)"
chooseText = "Choose Registry Key:"
keyText = "Key:"
valueText = "Value:"
valueName = "Value name:"
actionText = "Action:"
newValue = "New value:"
oldValue = "Current value:"
oldType = "Current Type:"
typeText = "Type:"
keyText2 = "Key"
noValueText = "value not found"
class RegistryChange:
name = "Change Registry Value"
description = "Changes a value in the windows registry"
actions = ("create or change", "change if exists only", "delete")
labels = (
'Change "%s" to %s',
'Change "%s" to %s if exists only',
'Delete "%s"'
)
class RegistryQuery:
name = "Query Registry"
description = "Queries the windows registry and return or compares the value"
actions = ("check if exists", "return as result", "compare to")
labels = (
'Check if "%s" exists',
'Return "%s" as result',
'Compare "%s" with %s'
)
regKeys = (
(_winreg.HKEY_CLASSES_ROOT, "HKEY_CLASSES_ROOT", "HKCR"),
(_winreg.HKEY_CURRENT_USER, "HKEY_CURRENT_USER", "HKCU"),
(_winreg.HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE", "HKLM"),
(_winreg.HKEY_USERS, "HKEY_USERS", "HKU"),
(_winreg.HKEY_CURRENT_CONFIG, "HKEY_CURRENT_CONFIG", "HKCC")
)
regTypes = (
(None, "Auto"),
(_winreg.REG_BINARY, "REG_BINARY"),
(_winreg.REG_DWORD, "REG_DWORD"),
(_winreg.REG_EXPAND_SZ, "REG_EXPAND_SZ"),
(_winreg.REG_MULTI_SZ, "REG_MULTI_SZ"),
(_winreg.REG_NONE, "REG_NONE"),
(_winreg.REG_SZ, "REG_SZ")
)
class RegistryLazyTree(wx.TreeCtrl):
def __init__(
self,
parent,
id=-1,
key = _winreg.HKEY_CURRENT_USER,
subkey = "Software",
valueName = None,
pos = wx.DefaultPosition,
size = wx.DefaultSize,
style = wx.TR_HAS_BUTTONS,
validator = wx.DefaultValidator,
name="RegistryLazyTree",
text = None
):
self.text = text
wx.TreeCtrl.__init__(self, parent, id, pos, size, style, validator, name)
self.SetImageList(eg.imageList)
self.SetMinSize((-1,200))
self.treeRoot = self.AddRoot(
"Registry",
image = eg.SetupIcons("root"),
data = wx.TreeItemData((True, None, None, None))
)
self.folderIcon = eg.SetupIcons("folder")
self.valueIcon = eg.SetupIcons("action")
#Adding keys
for item in regKeys:
#a tupel of 4 values is assigned to every item
#1) stores if the key has yet to be queried for subkey, when selected
#2) _winreg.hkey constant
#3) name of the key
#4) value name, None if just a key, empty string for default value
tmp = self.AppendItem(
self.treeRoot,
item[1],
image = self.folderIcon,
data =wx.TreeItemData((False, item[0], "", None))
)
self.SetItemHasChildren(tmp, True)
if item[0] == key:
self.SelectItem(tmp)
#select old value in tree
self.onTreeChange(wx.CommandEvent(), key, subkey, valueName)
self.EnsureVisible(self.GetSelection())
self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onTreeChange)
self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.OnExpandNode)
def GetValue(self):
data = self.GetItemData(self.GetSelection()).GetData()
return data[1], data[2], data[3]
def OnExpandNode(self, event):
self.onTreeChange(event, node = event.GetItem())
def onTreeChange(
self,
event,
key2Select = None,
subkey2Select = None,
valueName2Select = None,
node = None
):
#print "onTreeChange", key2Select, subkey2Select, valueName2Select
if not node:
node = self.GetSelection()
keyHasBeenQueried, fatherKey,\
fatherSubkey, fatherValueName = self.GetItemData(node).GetData()
subkey2Find = None
newItemSelected = False
if not keyHasBeenQueried:#check for subkeys
self.SetItemData(node,
wx.TreeItemData((True, fatherKey, fatherSubkey, fatherValueName)))
#buildung tree
try:
regHandle = _winreg.OpenKey(fatherKey, fatherSubkey)
except EnvironmentError, e:
eg.PrintError(self.text.keyOpenError + ": " + str(e))
return 0
#query subkeys
if len(fatherSubkey) == 0:
parentSubkey = ""
else:
parentSubkey = fatherSubkey + "\\"
#preparing strings to find the subkey2Select key
if valueName2Select:
valueName2Select = valueName2Select.lower()
if subkey2Select:
subkey2Select = subkey2Select.lower()
if key2Select and subkey2Select and key2Select == fatherKey:
length = len(fatherSubkey)
if subkey2Select[0:length] == fatherSubkey.lower():
subkey2Find = subkey2Select[length:]
if subkey2Find.startswith("\\"):
subkey2Find = subkey2Find[1:]
subkeys = subkey2Find.split("\\", 1)
subkey2Find = subkeys[0]
#building Tree
keyNames, valueList = RegEnumKeysAndValues(regHandle)
#sorting
keyNames.sort(lambda a,b: cmp(a[0].lower(), b[0].lower()) )
valueList.sort(lambda a,b: cmp(a[0].lower(), b[0].lower()) )
#subkeys
for keyName, numSubKeys, numSubValues in keyNames:
hasChildren = bool(numSubKeys + numSubValues > 0)
data = (
not hasChildren,
fatherKey,
parentSubkey + keyName,
None
)
tmp = self.AppendItem(
node,
keyName,
image=self.folderIcon,
data=wx.TreeItemData(data)
)
if subkey2Find == keyName.lower():
newItemSelected = True
self.SelectItem(tmp)
self.SetItemHasChildren(tmp, hasChildren)
#values
for valueName, valueType in valueList:
if len(valueName) == 0:
enumValueName = self.text.defaultText
else:
enumValueName = valueName
data = (True, fatherKey, fatherSubkey, valueName)
tmp = self.AppendItem(
node,
enumValueName,
image = self.valueIcon,
data = wx.TreeItemData(data)
)
if (
valueName2Select != None
and valueName.lower() == valueName2Select
and subkey2Select == fatherSubkey.lower()
):
newItemSelected = True
self.SelectItem(tmp)
if newItemSelected:
self.onTreeChange(
wx.CommandEvent(),
key2Select,
subkey2Select,
valueName2Select
)
event.Skip()
class RegistryChooser(wx.Window):
def __init__(
self,
parent,
id = -1,
text = None,
key = _winreg.HKEY_CURRENT_USER,
subkey = "Software",
valueName = None,
pos = wx.DefaultPosition,
size = wx.DefaultSize,
style = wx.EXPAND
):
self.text = text
wx.Window.__init__(self, parent, id, pos, size, style)
sizer = wx.GridBagSizer(5, 5)
sizer.AddGrowableRow(1)
sizer.AddGrowableCol(3,2)
sizer.AddGrowableCol(5,1)
sizer.SetEmptyCellSize((0,0))
sizer.Add(
wx.StaticText(self, -1, self.text.chooseText),
(0, 0),
(1, 6),
flag = wx.ALIGN_CENTER_VERTICAL
)
sizer.Add(
wx.StaticText(self, -1, self.text.keyText),
(2, 0),
flag = wx.ALIGN_CENTER_VERTICAL
)
#key
keyChoice = wx.Choice(self, -1)
for i in range(0,len(regKeys)):
keyChoice.Append(regKeys[i][1])
if regKeys[i][0] == key:
keyChoice.SetSelection(i)
sizer.Add(keyChoice, (2, 1))
sizer.Add(
wx.StaticText(self, -1, "\\"),
(2, 2),
flag = wx.ALIGN_CENTER_VERTICAL
)
#subkey
subkeyCtrl = wx.TextCtrl(self, -1, subkey, size=(200,-1))
sizer.Add(subkeyCtrl, (2, 3), flag = wx.EXPAND)
sizer.Add(
wx.StaticText(self, -1, self.text.valueName),
(2, 4),
flag = wx.ALIGN_CENTER_VERTICAL
)
#old Value
sizer.Add(
wx.StaticText(self, -1, self.text.oldValue),
(3, 0),
flag = wx.ALIGN_CENTER_VERTICAL
)
self.oldValueCtrl = wx.TextCtrl(self, -1)
self.oldValueCtrl.Enable(False)
sizer.Add(
self.oldValueCtrl,
(3, 1),
(1, 3),
flag = wx.EXPAND
)
sizer.Add(
wx.StaticText(self, -1, self.text.oldType),
(3, 4),
flag = wx.ALIGN_CENTER_VERTICAL
)
self.oldTypeCtrl = wx.TextCtrl(self, -1)
self.oldTypeCtrl.Enable(False)
sizer.Add(
self.oldTypeCtrl,
(3, 5),
flag = wx.EXPAND
)
self.fillOldValue(key, subkey, valueName)
#Create TreeCtrl
tree = RegistryLazyTree(self, -1, key, subkey, valueName, text=text)
sizer.Add(tree, (1, 0), (1, 6), flag = wx.EXPAND)
if valueName == None:
valueName = ""
elif len(valueName) == 0:
valueName = self.text.defaultText
valueNameCtrl = wx.TextCtrl(self, -1, valueName, size=(100,-1))
sizer.Add(valueNameCtrl, (2, 5), flag = wx.EXPAND)
self.SetSizer(sizer)
self.SetAutoLayout(True)
sizer.Fit(self)
self.Layout()
self.SetMinSize(self.GetSize())
self.keyChoice = keyChoice
self.subkeyCtrl = subkeyCtrl
self.valueNameCtrl = valueNameCtrl
self.tree = tree
self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTreeSelect)
self.subkeyCtrl.Bind(wx.EVT_TEXT, self.OnSubkeyEnter)
self.Bind(wx.EVT_SIZE, self.OnSize)
def OnSubkeyEnter(self, event):
value = self.subkeyCtrl.GetValue()
if value.startswith("HK") and value.count("\\") > 0:
#probably a whole key pasted
tmp = value.split("\\", 1)
key = tmp[0].upper() #get first part
value = tmp[1]
for i in range(0,len(regKeys)):
if regKeys[i][1] == key or regKeys[i][2] == key:
self.keyChoice.SetSelection(i)
self.subkeyCtrl.SetValue(value)
break
event.Skip()
def OnTreeSelect(self, event):
key, subkey, valueName = self.tree.GetValue()
if key != None:#change only if not root node
if valueName == None:
self.valueNameCtrl.SetValue("")
elif len(valueName) == 0:
self.valueNameCtrl.SetValue(self.text.defaultText)
else:
self.valueNameCtrl.SetValue(valueName)
self.subkeyCtrl.SetValue(subkey)
for i in range(0,len(regKeys)):
if regKeys[i][0] == key:
self.keyChoice.SetSelection(i)
break
self.fillOldValue(key, subkey, valueName)
event.Skip()
def fillOldValue(self, key, subkey, valueName):
curType = None
curValue = None
if valueName != None:
try:
regHandle = _winreg.OpenKey(key, subkey)
regValue = _winreg.QueryValueEx(regHandle, valueName)
_winreg.CloseKey(regHandle)
for i in range(1,len(regTypes)):
if regTypes[i][0] == regValue[1]:
curType = regTypes[i][1]
break
except EnvironmentError, e:
curType = ""
curValue = self.text.noValueText
if len(curType) > 0:
try:
curValue = unicode(regValue[0])
except:
#convert to hex
curValue = "0x" + binascii.hexlify(regValue[0]).upper()
else:
curType = self.text.keyText2
curValue = ""
self.oldValueCtrl.SetValue(str(curValue))
self.oldTypeCtrl.SetValue(curType)
def OnSize(self, event):
if self.GetAutoLayout():
self.Layout()
def GetValue(self):
#key
key = regKeys[self.keyChoice.GetSelection()][0]
#subkey
subkey = self.subkeyCtrl.GetValue()
#valueName
valueName = self.valueNameCtrl.GetValue()
if len(valueName) == 0:
valueName = None
elif valueName == self.text.defaultText:
valueName = ""
return key, subkey, valueName
class Registry(eg.PluginClass):
text = Text
def __init__(self):
self.AddAction(RegistryChange)
self.AddAction(RegistryQuery)
self.lastKeySelected = _winreg.HKEY_CURRENT_USER
self.lastSubkeySelected = "Software"
self.lastValueNameSelected = None
def UpdateLastSelectedKeys(self, key, subkey, valueName):
self.lastKeySelected = key
self.lastSubkeySelected = subkey
self.lastValueNameSelected = valueName
def FullKeyName(self, key, subkey, valueName, maxSubkeyLength = 15):
label = "root"
if not key:
return label
for i in range(0,len(regKeys)):
if regKeys[i][0] == key:
label = regKeys[i][2]
break
if not subkey:
return label
if (
maxSubkeyLength
and len(subkey) > maxSubkeyLength
and subkey.count("\\") != 0
):
label += "\\...\\" + subkey.rsplit("\\", 1)[1]
else:
label += "\\" + subkey
if valueName == None:
return label
elif len(valueName) == 0:
return label + "\\" + self.text.defaultText
else:
return label + "\\" + valueName
class RegistryQuery(eg.ActionClass):
def __call__(self, key, subkey, valueName, action, compareValue):
if not key:#nothing selected
return None
success = False
try:
regHandle = _winreg.OpenKey(key, subkey)
success = True
except EnvironmentError, e:
pass
#key does not exist or is not readable
if not success:
if action == 0:
return False
elif action == 1:
return None
elif action == 2:
return False
#key found and no value specfied
if valueName == None:
if action == 0:
return True
eg.PrintError(self.text.noValueNameError)
if action == 1:
return None
elif action == 2:
return False
#reading value
try:
regValue = _winreg.QueryValueEx(regHandle, valueName)
value = regValue[0]
if action == 0:
return True
elif action == 1:
return value
elif action == 2:
return str(value) == compareValue
except EnvironmentError, e:
if action == 0:
return False
elif action == 1:
return None
elif action == 2:
return False
def GetLabel(self, key, subkey, valueName, action, compareValue):
hkey = self.plugin.FullKeyName(key, subkey, valueName)
if action == 2:
return self.text.labels[action] % (hkey, compareValue)
return self.text.labels[action] % hkey
def Configure(
self,
key = None,
subkey = None,
valueName = None,
action = 0,
compareValue = ""
):
text = self.text
plugin = self.plugin
if key == None:
key = plugin.lastKeySelected
subkey = plugin.lastSubkeySelected
valueName = plugin.lastValueNameSelected
else:
plugin.lastKeySelected = key
plugin.lastSubkeySelected = subkey
plugin.lastValueNameSelected = valueName
dialog = eg.ConfigurationDialog(self, resizeable=True)
#keyChooser
regChooserCtrl = RegistryChooser(
dialog,
-1,
plugin.text,
key,
subkey,
valueName
)
def updateLastSelectedKeys(event):
#print "updateLastSelectedKeys", self.plugin.lastKeySelected, self.plugin.lastSubkeySelected, self.plugin.lastValueNameSelected, "Ctrl", regChooserCtrl.GetValue()
a, b, c = regChooserCtrl.tree.GetValue()
plugin.lastKeySelected = a
plugin.lastSubkeySelected = b
plugin.lastValueNameSelected = c
event.Skip()
regChooserCtrl.tree.Bind(wx.EVT_TREE_SEL_CHANGED, updateLastSelectedKeys)
dialog.sizer.Add(regChooserCtrl, 1, flag = wx.EXPAND)
dialog.sizer.Add(wx.Size(5,5))
choices = len(text.actions)
rb = range(0,choices)
sizer2 = wx.FlexGridSizer(1, choices + 2, 5, 5)
sizer2.AddGrowableCol(4)
sizer2.Add(
wx.StaticText(dialog, -1, plugin.text.actionText),
flag = wx.ALIGN_CENTER_VERTICAL
)
def onRadioButton(event):
flag = rb[2].GetValue()
compareValueCtrl.Enable(flag)
event.Skip()
rb[0] = wx.RadioButton(
dialog,
-1,
text.actions[0],
style = wx.RB_GROUP
)
rb[0].SetValue(action == 0)
sizer2.Add(rb[0], flag = wx.ALIGN_CENTER_VERTICAL)
rb[1] = wx.RadioButton(dialog, -1, text.actions[1])
rb[1].SetValue(action == 1)
sizer2.Add(rb[1], flag = wx.ALIGN_CENTER_VERTICAL)
rb[2] = wx.RadioButton(dialog, -1, text.actions[2])
rb[2].SetValue(action == 2)
sizer2.Add(rb[2], flag = wx.ALIGN_CENTER_VERTICAL)
compareValueCtrl = wx.TextCtrl(dialog, -1, compareValue, size=(200,-1)) #, size=(200,-1)
sizer2.Add(compareValueCtrl, flag = wx.EXPAND)
onRadioButton(wx.CommandEvent())
rb[0].Bind(wx.EVT_RADIOBUTTON, onRadioButton)
rb[1].Bind(wx.EVT_RADIOBUTTON, onRadioButton)
rb[2].Bind(wx.EVT_RADIOBUTTON, onRadioButton)
dialog.sizer.Add(sizer2, flag = wx.EXPAND)
if dialog.AffirmedShowModal():
key, subkey, valueName = regChooserCtrl.GetValue()
compareValue = compareValueCtrl.GetValue()
for i in range(0,3):
if rb[i].GetValue():
action = i
break
return (key, subkey, valueName, action, compareValue)
class RegistryChange(eg.ActionClass):
def __call__(self, key, subkey, valueName, action, keyType, newValue):
if not key:
eg.PrintError(self.plugin.text.noKeyError)
return 0
if not subkey:
eg.PrintError(self.plugin.text.noSubkeyError)
return 0
if not valueName:
eg.PrintError(self.plugin.text.noValueNameError)
return 0
#try to get handle
try:
if action == 0:
regHandle = _winreg.CreateKey(key, subkey)
else:
regHandle = _winreg.OpenKey(
key,
subkey,
0,
_winreg.KEY_WRITE | _winreg.KEY_READ
)
except EnvironmentError, e:
if action != 1:
eg.PrintError(self.plugin.text.keyOpenError + ": " + str(e))
return 0
#getting old value
oldType = None
try:
regValue = _winreg.QueryValueEx(regHandle, valueName)
oldType = regValue[1]
except EnvironmentError, e:
#exit because value does not exist
if (action == 1):
_winreg.CloseKey(regHandle)
return 1
if (action == 2):
_winreg.CloseKey(regHandle)
return 0
#try to determine type if none is given
if ((action == 0) or (action == 1)) and keyType == None:
if oldType == None:
try:
int(newValue)
#is int
keyType = _winreg.REG_DWORD
except ValueError, e:
if newValue.count("%") > 1:
keyType = _winreg.REG_EXPAND_SZ
else:
keyType = _winreg.REG_SZ
#if key already exists use the old type
else:
keyType = oldType
#set or delete key
try:
if (action == 0) or (action == 1):
if keyType == _winreg.REG_DWORD:
newValue = int(newValue)
#change key
_winreg.SetValueEx(regHandle, valueName, 0, keyType, newValue)
elif (action == 2):
#delete value
_winreg.DeleteValue(regHandle, valueName)
return 1
except (EnvironmentError, ValueError), e:
eg.PrintError(self.plugin.text.valueChangeError + ": " + str(e))
return 0
def GetLabel(self, key, subkey, valueName, action, keyType, newValue):
hkey = self.plugin.FullKeyName(key, subkey, valueName)
if action == 2:
return self.text.labels[action] % hkey
return self.text.labels[action] % (hkey, newValue)
def Configure(
self,
key = None,
subkey = None,
valueName = None,
action = 0,
keyType = None,
newValue = ""
):
text = self.text
plugin = self.plugin
if key == None:
key = plugin.lastKeySelected
subkey = plugin.lastSubkeySelected
valueName = plugin.lastValueNameSelected
else:
plugin.lastKeySelected = key
plugin.lastSubkeySelected = subkey
plugin.lastValueNameSelected = valueName
dialog = eg.ConfigurationDialog(self)
#keyChooser
regChooserCtrl = RegistryChooser(
dialog,
-1,
plugin.text,
key,
subkey,
valueName
)
def updateLastSelectedKeys(event):
a, b, c = regChooserCtrl.tree.GetValue()
plugin.lastKeySelected = a
plugin.lastSubkeySelected = b
plugin.lastValueNameSelected = c
event.Skip()
regChooserCtrl.Bind(wx.EVT_TREE_SEL_CHANGED, updateLastSelectedKeys)
dialog.sizer.Add(regChooserCtrl, 1, flag = wx.EXPAND)
dialog.sizer.Add(wx.Size(5,5))
#Action
actionSizer = wx.BoxSizer(wx.HORIZONTAL)
choices = len(text.actions)
rb = range(0, choices)
actionSizer.Add(
wx.StaticText(dialog, -1, plugin.text.actionText),
flag = wx.ALIGN_CENTER_VERTICAL
)
def onRadioButton(event):#disables elements depending on action selection
flag = not rb[2].GetValue()
newValueCtrl.Enable(flag)
typeChoice.Enable(flag)
event.Skip()
rb[0] = wx.RadioButton(dialog, -1, text.actions[0], style = wx.RB_GROUP)
rb[0].SetValue(action == 0)
actionSizer.Add(rb[0], flag = wx.ALIGN_CENTER_VERTICAL)
rb[1] = wx.RadioButton(dialog, -1, text.actions[1])
rb[1].SetValue(action == 1)
actionSizer.Add(rb[1], flag = wx.ALIGN_CENTER_VERTICAL)
rb[2] = wx.RadioButton(dialog, -1, text.actions[2])
rb[2].SetValue(action == 2)
actionSizer.Add(rb[2], flag = wx.ALIGN_CENTER_VERTICAL)
dialog.sizer.Add(actionSizer)
dialog.sizer.Add(wx.Size(5,5))
#new Value Input
newValueSizer = wx.FlexGridSizer(1, 4, 5, 5)
newValueSizer.AddGrowableCol(1)
newValueSizer.Add(
wx.StaticText(dialog, -1, plugin.text.newValue),
flag = wx.ALIGN_CENTER_VERTICAL
)
newValueCtrl = wx.TextCtrl(dialog, -1, newValue, size=(200,-1))
newValueSizer.Add(newValueCtrl, flag = wx.EXPAND)
newValueSizer.Add(
wx.StaticText(dialog, -1, plugin.text.typeText),
flag = wx.ALIGN_CENTER_VERTICAL
)
typeChoice = wx.Choice(dialog, -1)
for i, value in enumerate(regTypes):
typeChoice.Append(value[1])
if value[0] == keyType:
typeChoice.SetSelection(i)
newValueSizer.Add(typeChoice)
onRadioButton(wx.CommandEvent())
rb[0].Bind(wx.EVT_RADIOBUTTON, onRadioButton)
rb[1].Bind(wx.EVT_RADIOBUTTON, onRadioButton)
rb[2].Bind(wx.EVT_RADIOBUTTON, onRadioButton)
dialog.sizer.Add(newValueSizer, flag = wx.EXPAND)
if dialog.AffirmedShowModal():
key, subkey, valueName = regChooserCtrl.GetValue()
for i, item in enumerate(rb):
if item.GetValue():
action = i
break
keyType = regTypes[typeChoice.GetSelection()][0]
newValue = newValueCtrl.GetValue()
return (key, subkey, valueName, action, keyType, newValue)
Last edited by Bartman on Mon Sep 11, 2006 6:24 pm, edited 3 times in total.
- Bitmonster
- Site Admin
- Posts: 2239
- Joined: Mon Feb 06, 2006 10:28 pm
Ich habe deinen Source da oben mal direkt geändert.
1. Die Actions als Toplevel-Klassen gemacht, damit man gleich eine Einr├╝ckung spart.
2. Lange Zeilen umgebrochen.
3. RegistryLazyTree hatte noch direkt einen Zugriff auf die Text-Klasse. Habe ich über Parameter geändert.
4. Manche Zugriffe auf self.text und self.plugin durch lokale Variablen verk├╝rzt.
Das Control was du suchst, nennt sich wx.ComboBox.
1. Die Actions als Toplevel-Klassen gemacht, damit man gleich eine Einr├╝ckung spart.
2. Lange Zeilen umgebrochen.
3. RegistryLazyTree hatte noch direkt einen Zugriff auf die Text-Klasse. Habe ich über Parameter geändert.
4. Manche Zugriffe auf self.text und self.plugin durch lokale Variablen verk├╝rzt.
Das Control was du suchst, nennt sich wx.ComboBox.
- Bitmonster
- Site Admin
- Posts: 2239
- Joined: Mon Feb 06, 2006 10:28 pm
Noch ne Kleinigkeit:
Du machst oft sowas wie:
if fatherData[3] != None:
Mir ist dann immer nicht klar, was fatherData[3] ist. Besser wäre es (wenn da sonst nichts dagegen spricht) erst am Anfang fatherData zu entpacken in Variablen, die etwas aussagekräftiger sind. Also sowas wie:
key, value, keyParent, wasWeissIch = fatherData
Das ist dann im Endeffekt auch schneller, da Python mit lokalen Variablen schneller arbeitet als mit einem List-Index.
Jetzt sind es schon 800 Zeilen.
Du machst oft sowas wie:
if fatherData[3] != None:
Mir ist dann immer nicht klar, was fatherData[3] ist. Besser wäre es (wenn da sonst nichts dagegen spricht) erst am Anfang fatherData zu entpacken in Variablen, die etwas aussagekräftiger sind. Also sowas wie:
key, value, keyParent, wasWeissIch = fatherData
Das ist dann im Endeffekt auch schneller, da Python mit lokalen Variablen schneller arbeitet als mit einem List-Index.
Jetzt sind es schon 800 Zeilen.
- Bitmonster
- Site Admin
- Posts: 2239
- Joined: Mon Feb 06, 2006 10:28 pm
Dann fehlt erstmal nur noch eine __info__.py, dann kann ich das Plugin mal mit aufnehmen.
Mit der Value_anzeige sollte man aber wirklich noch etwas machen. Also da w├╝rde ich dann schon eher eine weitere Zeile opfern damit man dort ein "Current Value" Control hat. Am besten sieht wohl ein TextCtrl aus, dass man disabled hat.
Mit der Value_anzeige sollte man aber wirklich noch etwas machen. Also da w├╝rde ich dann schon eher eine weitere Zeile opfern damit man dort ein "Current Value" Control hat. Am besten sieht wohl ein TextCtrl aus, dass man disabled hat.
Code: Select all
name = "Registry"
author = "Bartman"
version = "1.0.0"
description = "Queries or changes values in the windows registry"