Spaces:
Sleeping
Sleeping
import commctrl | |
import win32api | |
import win32con | |
import win32ui | |
from pywin.mfc import dialog | |
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, int(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() | |