122 lines
3.7 KiB
Python
122 lines
3.7 KiB
Python
from pywin.mfc import dialog
|
|
import win32ui, win32con, commctrl, win32api
|
|
|
|
class ListDialog (dialog.Dialog):
|
|
|
|
def __init__ (self, title, list):
|
|
dialog.Dialog.__init__ (self, self._maketemplate(title))
|
|
self.HookMessage (self.on_size, win32con.WM_SIZE)
|
|
self.HookNotify(self.OnListItemChange, commctrl.LVN_ITEMCHANGED)
|
|
self.HookCommand(self.OnListClick, win32ui.IDC_LIST1)
|
|
self.items = list
|
|
|
|
def _maketemplate(self, title):
|
|
style = win32con.WS_DLGFRAME | win32con.WS_SYSMENU | win32con.WS_VISIBLE
|
|
ls = (
|
|
win32con.WS_CHILD |
|
|
win32con.WS_VISIBLE |
|
|
commctrl.LVS_ALIGNLEFT |
|
|
commctrl.LVS_REPORT
|
|
)
|
|
bs = (
|
|
win32con.WS_CHILD |
|
|
win32con.WS_VISIBLE
|
|
)
|
|
return [ [title, (0, 0, 200, 200), style, None, (8, "MS Sans Serif")],
|
|
["SysListView32", None, win32ui.IDC_LIST1, (0, 0, 200, 200), ls],
|
|
[128, "OK", win32con.IDOK, (10, 0, 50, 14), bs | win32con.BS_DEFPUSHBUTTON],
|
|
[128, "Cancel",win32con.IDCANCEL,(0, 0, 50, 14), bs],
|
|
]
|
|
|
|
def FillList(self):
|
|
size = self.GetWindowRect()
|
|
width = size[2] - size[0] - (10)
|
|
itemDetails = (commctrl.LVCFMT_LEFT, width, "Item", 0)
|
|
self.itemsControl.InsertColumn(0, itemDetails)
|
|
index = 0
|
|
for item in self.items:
|
|
index = self.itemsControl.InsertItem(index+1, str(item), 0)
|
|
|
|
def OnListClick(self, id, code):
|
|
if code==commctrl.NM_DBLCLK:
|
|
self.EndDialog(win32con.IDOK)
|
|
return 1
|
|
|
|
def OnListItemChange(self,std, extra):
|
|
(hwndFrom, idFrom, code), (itemNotify, sub, newState, oldState, change, point, lparam) = std, extra
|
|
oldSel = (oldState & commctrl.LVIS_SELECTED)!=0
|
|
newSel = (newState & commctrl.LVIS_SELECTED)!=0
|
|
if oldSel != newSel:
|
|
try:
|
|
self.selecteditem = itemNotify
|
|
self.butOK.EnableWindow(1)
|
|
except win32ui.error:
|
|
self.selecteditem = None
|
|
|
|
|
|
def OnInitDialog (self):
|
|
rc = dialog.Dialog.OnInitDialog (self)
|
|
self.itemsControl = self.GetDlgItem(win32ui.IDC_LIST1)
|
|
self.butOK = self.GetDlgItem(win32con.IDOK)
|
|
self.butCancel = self.GetDlgItem(win32con.IDCANCEL)
|
|
|
|
self.FillList()
|
|
|
|
size = self.GetWindowRect()
|
|
self.LayoutControls(size[2]-size[0], size[3]-size[1])
|
|
self.butOK.EnableWindow(0) # wait for first selection
|
|
return rc
|
|
|
|
def LayoutControls(self, w, h):
|
|
self.itemsControl.MoveWindow((0,0,w,h-30))
|
|
self.butCancel.MoveWindow((10, h-24, 60, h-4))
|
|
self.butOK.MoveWindow((w-60, h-24, w-10, h-4))
|
|
|
|
def on_size (self, params):
|
|
lparam = params[3]
|
|
w = win32api.LOWORD(lparam)
|
|
h = win32api.HIWORD(lparam)
|
|
self.LayoutControls(w, h)
|
|
|
|
class ListsDialog(ListDialog):
|
|
def __init__(self, title, list, colHeadings = ['Item']):
|
|
ListDialog.__init__(self, title, list)
|
|
self.colHeadings = colHeadings
|
|
|
|
def FillList(self):
|
|
index = 0
|
|
size = self.GetWindowRect()
|
|
width = size[2] - size[0] - (10) - win32api.GetSystemMetrics(win32con.SM_CXVSCROLL)
|
|
numCols = len(self.colHeadings)
|
|
|
|
for col in self.colHeadings:
|
|
itemDetails = (commctrl.LVCFMT_LEFT, width/numCols, col, 0)
|
|
self.itemsControl.InsertColumn(index, itemDetails)
|
|
index = index + 1
|
|
index = 0
|
|
for items in self.items:
|
|
index = self.itemsControl.InsertItem(index+1, str(items[0]), 0)
|
|
for itemno in range(1,numCols):
|
|
item = items[itemno]
|
|
self.itemsControl.SetItemText(index, itemno, str(item))
|
|
|
|
def SelectFromList (title, lst):
|
|
dlg = ListDialog(title, lst)
|
|
if dlg.DoModal()==win32con.IDOK:
|
|
return dlg.selecteditem
|
|
else:
|
|
return None
|
|
|
|
def SelectFromLists (title, lists, headings):
|
|
dlg = ListsDialog(title, lists, headings)
|
|
if dlg.DoModal()==win32con.IDOK:
|
|
return dlg.selecteditem
|
|
else:
|
|
return None
|
|
|
|
def test():
|
|
# print SelectFromList('Single list', [1,2,3])
|
|
print(SelectFromLists('Multi-List', [ ('1',1, 'a'), ('2',2, 'b'), ('3',3, 'c' )], ['Col 1', 'Col 2']))
|
|
|
|
if __name__=='__main__':
|
|
test()
|