list.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. from pywin.mfc import dialog
  2. import win32ui, win32con, commctrl, win32api
  3. class ListDialog (dialog.Dialog):
  4. def __init__ (self, title, list):
  5. dialog.Dialog.__init__ (self, self._maketemplate(title))
  6. self.HookMessage (self.on_size, win32con.WM_SIZE)
  7. self.HookNotify(self.OnListItemChange, commctrl.LVN_ITEMCHANGED)
  8. self.HookCommand(self.OnListClick, win32ui.IDC_LIST1)
  9. self.items = list
  10. def _maketemplate(self, title):
  11. style = win32con.WS_DLGFRAME | win32con.WS_SYSMENU | win32con.WS_VISIBLE
  12. ls = (
  13. win32con.WS_CHILD |
  14. win32con.WS_VISIBLE |
  15. commctrl.LVS_ALIGNLEFT |
  16. commctrl.LVS_REPORT
  17. )
  18. bs = (
  19. win32con.WS_CHILD |
  20. win32con.WS_VISIBLE
  21. )
  22. return [ [title, (0, 0, 200, 200), style, None, (8, "MS Sans Serif")],
  23. ["SysListView32", None, win32ui.IDC_LIST1, (0, 0, 200, 200), ls],
  24. [128, "OK", win32con.IDOK, (10, 0, 50, 14), bs | win32con.BS_DEFPUSHBUTTON],
  25. [128, "Cancel",win32con.IDCANCEL,(0, 0, 50, 14), bs],
  26. ]
  27. def FillList(self):
  28. size = self.GetWindowRect()
  29. width = size[2] - size[0] - (10)
  30. itemDetails = (commctrl.LVCFMT_LEFT, width, "Item", 0)
  31. self.itemsControl.InsertColumn(0, itemDetails)
  32. index = 0
  33. for item in self.items:
  34. index = self.itemsControl.InsertItem(index+1, str(item), 0)
  35. def OnListClick(self, id, code):
  36. if code==commctrl.NM_DBLCLK:
  37. self.EndDialog(win32con.IDOK)
  38. return 1
  39. def OnListItemChange(self,std, extra):
  40. (hwndFrom, idFrom, code), (itemNotify, sub, newState, oldState, change, point, lparam) = std, extra
  41. oldSel = (oldState & commctrl.LVIS_SELECTED)!=0
  42. newSel = (newState & commctrl.LVIS_SELECTED)!=0
  43. if oldSel != newSel:
  44. try:
  45. self.selecteditem = itemNotify
  46. self.butOK.EnableWindow(1)
  47. except win32ui.error:
  48. self.selecteditem = None
  49. def OnInitDialog (self):
  50. rc = dialog.Dialog.OnInitDialog (self)
  51. self.itemsControl = self.GetDlgItem(win32ui.IDC_LIST1)
  52. self.butOK = self.GetDlgItem(win32con.IDOK)
  53. self.butCancel = self.GetDlgItem(win32con.IDCANCEL)
  54. self.FillList()
  55. size = self.GetWindowRect()
  56. self.LayoutControls(size[2]-size[0], size[3]-size[1])
  57. self.butOK.EnableWindow(0) # wait for first selection
  58. return rc
  59. def LayoutControls(self, w, h):
  60. self.itemsControl.MoveWindow((0,0,w,h-30))
  61. self.butCancel.MoveWindow((10, h-24, 60, h-4))
  62. self.butOK.MoveWindow((w-60, h-24, w-10, h-4))
  63. def on_size (self, params):
  64. lparam = params[3]
  65. w = win32api.LOWORD(lparam)
  66. h = win32api.HIWORD(lparam)
  67. self.LayoutControls(w, h)
  68. class ListsDialog(ListDialog):
  69. def __init__(self, title, list, colHeadings = ['Item']):
  70. ListDialog.__init__(self, title, list)
  71. self.colHeadings = colHeadings
  72. def FillList(self):
  73. index = 0
  74. size = self.GetWindowRect()
  75. width = size[2] - size[0] - (10) - win32api.GetSystemMetrics(win32con.SM_CXVSCROLL)
  76. numCols = len(self.colHeadings)
  77. for col in self.colHeadings:
  78. itemDetails = (commctrl.LVCFMT_LEFT, width/numCols, col, 0)
  79. self.itemsControl.InsertColumn(index, itemDetails)
  80. index = index + 1
  81. index = 0
  82. for items in self.items:
  83. index = self.itemsControl.InsertItem(index+1, str(items[0]), 0)
  84. for itemno in range(1,numCols):
  85. item = items[itemno]
  86. self.itemsControl.SetItemText(index, itemno, str(item))
  87. def SelectFromList (title, lst):
  88. dlg = ListDialog(title, lst)
  89. if dlg.DoModal()==win32con.IDOK:
  90. return dlg.selecteditem
  91. else:
  92. return None
  93. def SelectFromLists (title, lists, headings):
  94. dlg = ListsDialog(title, lists, headings)
  95. if dlg.DoModal()==win32con.IDOK:
  96. return dlg.selecteditem
  97. else:
  98. return None
  99. def test():
  100. # print SelectFromList('Single list', [1,2,3])
  101. print SelectFromLists('Multi-List', [ ('1',1, 'a'), ('2',2, 'b'), ('3',3, 'c' )], ['Col 1', 'Col 2'])
  102. if __name__=='__main__':
  103. test()