codekingpro/portable-devtools
114k
1import commctrl2import win32api3import win32con4import win32ui5from pywin.mfc import dialog6 7 8class ListDialog(dialog.Dialog):9 def __init__(self, title, list):10 dialog.Dialog.__init__(self, self._maketemplate(title))11 self.HookMessage(self.on_size, win32con.WM_SIZE)12 self.HookNotify(self.OnListItemChange, commctrl.LVN_ITEMCHANGED)13 self.HookCommand(self.OnListClick, win32ui.IDC_LIST1)14 self.items = list15 16 def _maketemplate(self, title):17 style = win32con.WS_DLGFRAME | win32con.WS_SYSMENU | win32con.WS_VISIBLE18 ls = (19 win32con.WS_CHILD20 | win32con.WS_VISIBLE21 | commctrl.LVS_ALIGNLEFT22 | commctrl.LVS_REPORT23 )24 bs = win32con.WS_CHILD | win32con.WS_VISIBLE25 return [26 [title, (0, 0, 200, 200), style, None, (8, "MS Sans Serif")],27 ["SysListView32", None, win32ui.IDC_LIST1, (0, 0, 200, 200), ls],28 [128, "OK", win32con.IDOK, (10, 0, 50, 14), bs | win32con.BS_DEFPUSHBUTTON],29 [128, "Cancel", win32con.IDCANCEL, (0, 0, 50, 14), bs],30 ]31 32 def FillList(self):33 size = self.GetWindowRect()34 width = size[2] - size[0] - (10)35 itemDetails = (commctrl.LVCFMT_LEFT, width, "Item", 0)36 self.itemsControl.InsertColumn(0, itemDetails)37 index = 038 for item in self.items:39 index = self.itemsControl.InsertItem(index + 1, str(item), 0)40 41 def OnListClick(self, id, code):42 if code == commctrl.NM_DBLCLK:43 self.EndDialog(win32con.IDOK)44 return 145 46 def OnListItemChange(self, std, extra):47 (hwndFrom, idFrom, code), (48 itemNotify,49 sub,50 newState,51 oldState,52 change,53 point,54 lparam,55 ) = (std, extra)56 oldSel = (oldState & commctrl.LVIS_SELECTED) != 057 newSel = (newState & commctrl.LVIS_SELECTED) != 058 if oldSel != newSel:59 try:60 self.selecteditem = itemNotify61 self.butOK.EnableWindow(1)62 except win32ui.error:63 self.selecteditem = None64 65 def OnInitDialog(self):66 rc = dialog.Dialog.OnInitDialog(self)67 self.itemsControl = self.GetDlgItem(win32ui.IDC_LIST1)68 self.butOK = self.GetDlgItem(win32con.IDOK)69 self.butCancel = self.GetDlgItem(win32con.IDCANCEL)70 71 self.FillList()72 73 size = self.GetWindowRect()74 self.LayoutControls(size[2] - size[0], size[3] - size[1])75 self.butOK.EnableWindow(0) # wait for first selection76 return rc77 78 def LayoutControls(self, w, h):79 self.itemsControl.MoveWindow((0, 0, w, h - 30))80 self.butCancel.MoveWindow((10, h - 24, 60, h - 4))81 self.butOK.MoveWindow((w - 60, h - 24, w - 10, h - 4))82 83 def on_size(self, params):84 lparam = params[3]85 w = win32api.LOWORD(lparam)86 h = win32api.HIWORD(lparam)87 self.LayoutControls(w, h)88 89 90class ListsDialog(ListDialog):91 def __init__(self, title, list, colHeadings=["Item"]):92 ListDialog.__init__(self, title, list)93 self.colHeadings = colHeadings94 95 def FillList(self):96 index = 097 size = self.GetWindowRect()98 width = (99 size[2] - size[0] - (10) - win32api.GetSystemMetrics(win32con.SM_CXVSCROLL)100 )101 numCols = len(self.colHeadings)102 103 for col in self.colHeadings:104 itemDetails = (commctrl.LVCFMT_LEFT, int(width / numCols), col, 0)105 self.itemsControl.InsertColumn(index, itemDetails)106 index = index + 1107 index = 0108 for items in self.items:109 index = self.itemsControl.InsertItem(index + 1, str(items[0]), 0)110 for itemno in range(1, numCols):111 item = items[itemno]112 self.itemsControl.SetItemText(index, itemno, str(item))113 114 115def SelectFromList(title, lst):116 dlg = ListDialog(title, lst)117 if dlg.DoModal() == win32con.IDOK:118 return dlg.selecteditem119 else:120 return None121 122 123def SelectFromLists(title, lists, headings):124 dlg = ListsDialog(title, lists, headings)125 if dlg.DoModal() == win32con.IDOK:126 return dlg.selecteditem127 else:128 return None129 130 131def test():132 # print SelectFromList('Single list', [1,2,3])133 print(134 SelectFromLists(135 "Multi-List",136 [("1", 1, "a"), ("2", 2, "b"), ("3", 3, "c")],137 ["Col 1", "Col 2"],138 )139 )140 141 142if __name__ == "__main__":143 test()144 