windows MFC - 显示对话框后立即执行代码(.NET 等效于 Form.Shown)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/269462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 11:34:28  来源:igfitidea点击:

MFC - execute code right after dialog is shown (.NET equivalent of Form.Shown)

windowsmfcdialog

提问by Sumrak

I'm doing some small changes to C++ MFC project. I'm .NET developer so Windows programming is new to me.

我正在对 C++ MFC 项目做一些小的改动。我是 .NET 开发人员,所以 Windows 编程对我来说是新的。

I need to launch some method right after CDialog is completely shown (painted) for the first time, but only once.

我需要在 CDialog 第一次完全显示(绘制)后立即启动一些方法,但只有一次。

How can I do this? In .NET I would handle Form.Shownevent.

我怎样才能做到这一点?在 .NET 中,我会处理Form.Shown事件。

Do I need to handle some message? Which? Do I need to override some CDialog method? Or is there no easy way? I'm thinking of handling WM_ACTIVATE and then using a flag to ensure I call another method only once.

我需要处理一些消息吗?哪一个?我需要覆盖一些 CDialog 方法吗?还是没有简单的方法?我正在考虑处理 WM_ACTIVATE,然后使用一个标志来确保我只调用另一个方法一次。

采纳答案by Sumrak

Found the answer here: Waiting until the dialog box is displayed before doing something

在这里找到答案:等到对话框显示后再做某事

Short story:
INT_PTR CALLBACK
DlgProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
  switch (uiMsg) {

  case WM_INITDIALOG:
    return TRUE;

  case WM_WINDOWPOSCHANGED:
    if ((((WINDOWPOS*)lParam)->flags & SWP_SHOWWINDOW) &&
        !g_fShown) {
      g_fShown = TRUE;
      PostMessage(hwnd, WM_APP, 0, 0);
    }
    break;


  case WM_APP:
      MessageBox(hwnd,
                 IsWindowVisible(hwnd) ? TEXT("Visible")
                                       : TEXT("Not Visible"),
                 TEXT("Title"), MB_OK);
      break;

  case WM_CLOSE:
   EndDialog(hwnd, 0);
   break;
  }

  return FALSE;
}

If you're using MFC like I am you'll need to map WM_WINDOWPOSCHANGED and then use ON_MESSAGE to map WM_APP. See this CodeProject articlefor more details.

如果您像我一样使用 MFC,则需要映射 WM_WINDOWPOSCHANGED,然后使用 ON_MESSAGE 映射 WM_APP。有关更多详细信息,请参阅此 CodeProject 文章

回答by Joel Lucsy

Another approach I've used a number of times with great success is to use a timer. Set it for 10m0s. It'll only fire after the dialog is shown.

我多次使用并取得巨大成功的另一种方法是使用计时器。将其设置为 10m0s。它只会在显示对话框后触发。

回答by baash05

Hell put the code in OnPaint() and thow a bool m_fullyInitilized in your class. I like the timer too.. Though I usually go with 100ms. I also move all my initilization code out of the oninit, in these cases.. Just to protect against too much processing in there.

地狱把代码放在 OnPaint() 中,并在你的类中放一个 bool m_fullyInitilized 。我也喜欢计时器..虽然我通常用 100 毫秒。在这些情况下,我还将所有初始化代码从 oninit 中移出。只是为了防止在那里进行过多的处理。

回答by SteveH

For reference you don't need to override DlgProc to intercept WM_WINDOWPOSCHANGED.

作为参考,您不需要覆盖 DlgProc 来拦截 WM_WINDOWPOSCHANGED。

   ON_WM_WINDOWPOSCHANGED()
   ON_MESSAGE(MyCDialog::MY_USER_MSG, OnDialogShown)

void MyCDialog::OnWindowPosChanged(WINDOWPOS *wndpos)
{
   __super::OnWindowPosChanged(wndpos);

   if (!mDialogShown && (wndpos->flags & SWP_SHOWWINDOW)) {
      PostMessage(MY_USER_MSG);
      mDialogShown = true;
   }
}

LRESULT MyCDialog::OnDialogShown(WPARAM, LPARAM)
{
   ...
}

You can implement the handling inline instead of posting another message if appropriate.

如果合适,您可以实施内联处理而不是发布另一条消息。