Python MFC : Updating static text in response to events

标签 python mfc

我有以下 Python MFC 代码。我有一个列表框,其中填充了一些值,当用户单击这些值时,我希望静态文本控件使用当前选择进行更新。这段代码有两个问题。第一个是文本控件中的值仅在我第一次单击列表框时更新。第二个是该值滞后于列表框中实际选定的值,可能是因为控件在调用我的处理程序代码后处理单击。如果您能帮助解决这两个问题,我将不胜感激。

一件奇怪的事情(也许是一个线索)是,当我将鼠标放在“确定”按钮上,但将鼠标移开以向上移动时,静态文本确实会按照我的预期进行更新。

我已经在控件和对话框上尝试过 RedrawWindow()、UpdateWindow()、ShowWindow(),但似乎没有任何区别。

import win32con
from pywin.mfc import dialog

IDC_LIST = 9000
IDC_TEXT = 9001

class ChooserDialog(dialog.Dialog):

  def __init__(self):
    DIALOGTEMPLATE = [  
      ["Test", (0, 0, 254, 199), win32con.WS_CAPTION | win32con.DS_MODALFRAME, None, (8, "MS SansSerif")],
      [128, "OK", win32con.IDOK, (197,178,50,14), win32con.BS_PUSHBUTTON | win32con.WS_VISIBLE],
      ["listbox", "List", IDC_LIST, (7,7,177,186), win32con.WS_VISIBLE],
      ["static", "", IDC_TEXT, (197,7,50,160), win32con.WS_CHILD | win32con.WS_VISIBLE]
    ]
    dialog.Dialog.__init__(self, DIALOGTEMPLATE)

  def OnInitDialog(self):
    rc = dialog.Dialog.OnInitDialog(self)
    for i in ["one", "two", "three"]:
      self.GetDlgItem(IDC_LIST).AddString(i)
    self.HookCommand(self.OnNotify, IDC_LIST)
    return rc

  def OnNotify(self, ctrl, action):
    if ctrl == IDC_LIST:
      selected = self.GetDlgItem(IDC_LIST).GetCurSel()
      self.SetDlgItemText(IDC_TEXT, "%d" % selected)
      self.GetDlgItem(IDC_TEXT).RedrawWindow()
    return 1

dia = ChooserDialog()
dia.DoModal()

最佳答案

代码的第一个问题是没有为列表框控件设置 win32con.LBS_NOTIFY 样式。如果未设置,您将不会收到来自 LB 的任何消息。我收到的几条消息是由于对话框中的其他事件引起的。

第二个问题是我使用了 HookCommand(),它拦截命令并允许您处理它们。相反,我希望 HookMes​​sage() 仅获取通知。看来在控件更新后会调用通知,所以这正是我想要的。

根据MSDN文档,LBN_SELCHANGE通知是通过WM_COMMAND消息接收的。看来我必须订阅对话框中的所有 WM_COMMAND 消息,然后在我的处理程序中过滤它们。 LBN_SELCHANGE 文档解释了传递的内容,结合 HookMes​​sage() Python 文档,您可以了解如何处理它。

这是工作代码:

    import win32con
    from pywin.mfc import dialog

    IDC_LIST = 9500
    IDC_TEXT = 9501

    class ChooserDialog(dialog.Dialog):

      def __init__(self):
        DIALOGTEMPLATE = [  
          ["Test", (0, 0, 254, 199), win32con.WS_CAPTION | win32con.DS_MODALFRAME, None, (8, "MS SansSerif")],
          [128, "OK", win32con.IDOK, (197,178,50,14), win32con.BS_PUSHBUTTON | win32con.WS_VISIBLE],
          ["listbox", "List", IDC_LIST, (7,7,177,186), win32con.WS_VISIBLE|win32con.LBS_NOTIFY],
          ["static", "", IDC_TEXT, (197,7,50,160), win32con.WS_CHILD | win32con.WS_VISIBLE]
        ]
        dialog.Dialog.__init__(self, DIALOGTEMPLATE)

      def OnInitDialog(self):
        rc = dialog.Dialog.OnInitDialog(self)
        for i in ["one", "two", "three"]:
          self.GetDlgItem(IDC_LIST).AddString(i)
        self.HookMessage(self.OnNotifyCommand, win32con.WM_COMMAND)
        return rc

      def OnNotifyCommand(self, data):
        msg_id = data[1]   # should always be WM_COMMAND
        wParam = data[2]
        lParam = data[3]
        list_id = wParam & 0xffff
        notification_code = (wParam & 0xffff0000) >> 16
        if list_id != IDC_LIST: return    # not our list box.
        if notification_code != win32con.LBN_SELCHANGE: return    # Not a change of selection
        selected = self.GetDlgItem(IDC_LIST).GetCurSel()
        self.SetDlgItemText(IDC_TEXT, "%d"%selected)

    dia = ChooserDialog()
    dia.DoModal()

关于Python MFC : Updating static text in response to events,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30650763/

相关文章:

python - 我是否需要创建/更新两个模型才能在 Flask 中插入一对多?

c++ - CFileDialog 在 Windows XP 下保留目录句柄

c++ - 解释这个宏

c++ - 从应用程序特定文件夹加载自定义字体文件

c++ - OpenGL 两个不同的 3d 渲染图片控件在单个 MFC 对话框上不起作用

python - 将 Perl 正则表达式转换为 python

python - 只计算一组中的男性

python - 如何为 graphql 查询配置 JSON?

python - 在 Python 中以正确的方式导入文件/模块

mfc - 使用 CSplitterWnd 在 CChildFrame 中创建多 View