【问题标题】:Win32 MessageBox doesn't appearWin32 消息框不出现
【发布时间】:2010-11-29 00:08:21
【问题描述】:

我遇到了一个奇怪的问题。我正在 VC++ 2008 中制作一个 Win32 应用程序,制作一个类来封装大部分工作,以便在调用 MessageBox 时轻松重复。消息框`已创建(我认为)但除非我按 Alt 键否则不会显示!

究竟发生了什么:

  1. 我运行程序

  2. 按 Enter

  3. 主窗口失去焦点

  4. 当我点击主窗口时发出哔哔声,就像存在模态消息框一样

  5. 要么按 Escape... 获得焦点,要么按 Alt 然后消息框出现并按下 alt 键(即菜单将下降)!!!!!!

附:它工作正常,但突然发生了这种情况。我没有发现任何不同 - 我什至做了一个新项目!

这应该是主程序:

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR    lpCmdLine, int       nCmdShow)
{
    MSG msg;
    CWnd    cMainWindow(TEXT("DentoMan"), TEXT("Bejkoman")); // pass The class name and window name to the constructor

    cMainWindow.CreateDef(); //Create the Window
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}

虽然这是类文件

CWnd::CWnd() {
};

CWnd::CWnd(LPTSTR lpszClassName, LPTSTR lpszWindowName) {
    CWnd::lpszClassName     = lpszClassName;
    CWnd::lpszWindowName    = lpszWindowName;
};

CWnd::~CWnd() {
};

// Create the window with default parameters
HWND CWnd::CreateDef(void) {
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = StaticWndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = (HINSTANCE)GetModuleHandle(NULL);
    wcex.hIcon          = 0;
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 4);
    wcex.lpszMenuName   = 0;
    wcex.lpszClassName  = lpszClassName;
    wcex.hIconSm        = 0;

    RegisterClassEx(&wcex);
    g_hWnd = CreateWindowEx(0,lpszClassName, lpszWindowName, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, wcex.hInstance, this);
    hInst   =   wcex.hInstance;  //Store hInstance in the class hInst variable

    if (!g_hWnd) return false;
    ShowWindow(g_hWnd, SW_SHOW);
    UpdateWindow(g_hWnd);

    return g_hWnd;
}

LRESULT CALLBACK CWnd::StaticWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    /* The Only Message we take here so we store the 'this' pointer within the window to identify messages 
    comming from it by the 'this' pointer*/
    if ( Message == WM_CREATE ) {
        SetWindowLong( hWnd, GWL_USERDATA, (LONG)((CREATESTRUCT FAR *)lParam)->lpCreateParams);
    }

    /* Store the window pointer in the class pointer we just created in order to run the right public WndPRoc */
    CWnd *Destination = (CWnd*)GetWindowLong( hWnd, GWL_USERDATA );

    // If the hWnd has a related class, pass it through
    if (Destination) {
        return Destination->WndProc( hWnd, Message, wParam, lParam );
    }

    // No destination found, defer to system...
    return DefWindowProc( hWnd, Message, wParam, lParam );
};

LRESULT CWnd::WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    // Determine message type
    switch (Message) {
        case WM_LBUTTONDOWN:
            {
                /* this is a common trick for easy dragging of the window.this message fools windows telling that the user is
                 actually dragging the application caption bar.*/
                 SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION,NULL);
                break;
            }

        /*case WM_CREATE:
            break;
    */

        case WM_CLOSE:
            PostQuitMessage(0);
            break;

        case WM_DESTROY:
            UnregisterClass(lpszClassName, hInst);
            PostQuitMessage(0);
            break;

        case WM_KEYDOWN:    //KeyBoard keys
            // Which key was pressed?
            switch (wParam) {
                case VK_ESCAPE: //close through escape key
                    PostQuitMessage(0);
                    return 0;
                case VK_RETURN:
                    MessageBox(hWnd, TEXT("DFGDGD"), TEXT("DFGDFG"), NULL);
                    return 0;
            } // End Switch

            break;

        case WM_COMMAND:
            /*switch(LOWORD(wParam))
        {
        }*/
        break;

        case WM_PAINT:
            break;

        default:
            return DefWindowProc(hWnd, Message, wParam, lParam);

    } // End Message Switch

return 0;
};

类头:

class CWnd {
    public:
        CWnd();
        CWnd(LPTSTR lpszClassName, LPTSTR lpszWindowName);
        virtual ~CWnd();
        virtual HWND CreateDef(void);           // Create the window with default parameters
        virtual LRESULT     WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam );

    private:
        static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
        HWND        g_hWnd;     //Global window handle for this window
        HINSTANCE   hInst;      //Global instance for this window

        LPTSTR          lpszClassName;
        LPTSTR          lpszWindowName;
};

附:我包含了所有需要的头文件,除了 MessageBox 一切都很好

这也是here上代码的链接

【问题讨论】:

  • 把相关代码贴在这里。另外,在黑暗中拍摄:在显示消息框时指定父窗口。
  • 已编辑,已删除链接。不要发布不安全的 .exe 文件。只需粘贴相关代码即可。
  • ...或者你可以把代码放到ideone或者pastebin
  • @Jim Brissom,您也可以在此函数中将 NULL 作为窗口句柄传递,它应该可以工作(至少在我的情况下可以)。不确定它是否正确(也许我应该使用HWND_DESKTOP 或其他东西),但它仍然有效。
  • 愿古老的帖子永不消亡... FWIW,我遇到了这个问题,其中 ::MessageBox() 没有出现(在名为 ::MessageBox() 的 win 64 MFC 应用程序中)。我可以通过将 AfxGetMainWnd()->m_hWnd 传递给 hWnd(而不是 nullptr)通过将 MB_DEFAULT_DESKTOP_ONLY 作为标志传递来修复它。

标签: messagebox winapi


【解决方案1】:

Ohhhhhhh 最后我找到了这个问题的解决方案......为了让每个人都受益这个问题是在 WM_PAINT 消息的 WndProc(.......) 中,我在其中编写了一些代码并删除了所有代码具有 BeginPaint 和 EndPaint 功能,因此一旦在其上绘制任何内容(包括该 MessageBox),程序就会进入冻结期,但它仅在我按 Alt 时显示,我认为因为在该步骤中控件已转移到系统以显示系统菜单(我想想)

解决方案要么删除 WM_PAINT 消息处理程序,要么添加正常的 BeginPaint 和 EndPaint 函数

感谢所有回答我问题的人

【讨论】:

    【解决方案2】:

    如果有人仍然感兴趣,这个方法有效:

    MessageBox(NULL,L"error",L"Error",MB_ICONERROR|MB_DEFAULT_DESKTOP_ONLY);
    

    【讨论】:

    • 我遇到了这个问题,添加 MB_DEFAULT_DESKTOP_ONLY 标志确实解决了。添加MB_TASKMODAL 也是如此。你有解释为什么这些标志可以解决这个问题吗?
    • (对不起,不,我很困惑,MB_TASKMODAL 没有解决问题,只有MB_DEFAULT_DESKTOP_ONLY 解决了。我很好奇这里发生了什么)
    【解决方案3】:

    正如上面提到的那样,我遇到了由 WM_PAINT 引起的类似问题。通过添加return DefWindowProc(hWnd, Message, wParam, lParam); 解决它。

    【讨论】:

      【解决方案4】:

      当您创建 MessageBox 时,您应该在 CreateWindowEx 中传递 WS_CHILD
      编辑 2:
      好的试试这个。

      MessageBox(hWnd, TEXT("DFGDGD"), TEXT("DFGDFG"), MB_OK);
      

      【讨论】:

      • 我做不到 Ramilol 这是我的主窗口,我正在通过它调用 MessageBox 函数...
      • 抱歉没有注意到...我不太明白您在说什么...您的消息框或主窗口没有显示?
      • 究竟发生了什么: 1 - 我运行程序 2 - 按 Enter 3 - 主窗口失去焦点 4 - 当我单击主窗口时发出哔声,就好像存在模式 MessageBox 5 - 要么按 Escape... 获得焦点,要么按 Alt 然后 MessageBox 出现并按下 alt 键(即菜单将下降)!!!!!!
      • 同样的问题可能是我的系统在将程序编译为 32 位时在 windows 7 x64 上工作!
      • @Ramilol 哦,我刚刚找到解决方案并添加了答案,感谢您的努力...如果您有任何意见请告诉我
      【解决方案5】:

      尝试使用 MB_TOPMOST: MessageBox(hWnd, TEXT("DFGDGD"), TEXT("DFGDFG"), MB_TOPMOST);

      【讨论】:

        猜你喜欢
        • 2011-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多