Win32消息框不显示

6
我遇到了一个奇怪的问题。我正在使用VC ++ 2008创建一个Win32应用程序,制作一个类来封装大部分工作,以便在调用MessageBox时轻松重复。消息框被创建(我想),但除非我按下Alt键,否则不会显示出来!
具体情况如下:
1. 运行程序 2. 按Enter键 3. 主窗口失去焦点 4. 当我点击主窗口时,发出蜂鸣声,就像存在一个模态MessageBox一样 5. 要么按Esc...获得焦点,要么按Alt,然后MessageBox出现,并按下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之外一切正常。

这也是代码链接:这里


2
请在此处发布相关代码。同时,为显示消息框指定一个父窗口可能是一种尝试。 - Jim Brissom
4
编辑后,已移除链接。不要发布不安全的 .exe 文件。请仅粘贴相关代码。 - Ruel
... 或者您可以将代码放到 ideone 或者 pastebin 上。 - Vlad
如果您使用null或任何其他处理方式,同样的问题会发生。 - Dr. Mina Mounir
1
愿古老的帖子永不消逝... 顺便说一下,我遇到了这个问题,在一个调用 ::MessageBox() 的 win 64 MFC 应用程序中,::MessageBox() 没有出现。我可以通过将 AfxGetMainWnd()->m_hWnd 作为 hWnd(而不是 nullptr)传递 或者 将 MB_DEFAULT_DESKTOP_ONLY 作为标志传递来解决它。 - Steve A
显示剩余2条评论
5个回答

12

哦,终于我找到了解决这个问题的方法...为了让每个人受益,问题出在WndProc(.......)的WM_PAINT消息上,我在其中写了一些代码,并删除了所有的BeginPaint和EndPaint函数,因此一旦任何东西被涂上(包括MessageBox),程序就会进入冻结期,但只有当我按下Alt键时才会显示,因为在那一步中控制被转移到系统菜单中(我想)。

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

感谢每一个回答我问题的人。


8

如果有人仍然感兴趣,这种方法是有效的:

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

我曾经遇到过这个问题,加上 MB_DEFAULT_DESKTOP_ONLY 标志解决了问题。添加 MB_TASKMODAL 也有同样的效果。你知道为什么这些标志会修复这个问题吗? - Oskar
抱歉,我搞错了,MB_TASKMODAL 没有解决问题,只有 MB_DEFAULT_DESKTOP_ONLY 才行。我非常好奇这里到底发生了什么。 - Oskar

3

我曾经遇到一个类似的问题,是由于WM_PAINT引起的,正如上面某人所提到的。在那里添加了return DefWindowProc(hWnd, Message, wParam, lParam);解决了这个问题。


2
当您创建消息框时,应在CreateWindowEx中传递WS_CHILD
编辑2:
好的,请尝试这样做。
MessageBox(hWnd, TEXT("DFGDGD"), TEXT("DFGDFG"), MB_OK);

我做不到,Ramilol。这是我的主窗口,我通过它调用了MessageBox函数... - Dr. Mina Mounir
抱歉没有注意到...我无法真正理解你所说的话..是你的消息框没有出现还是你的主窗口? - Ramilol
具体情况如下:1 - 运行程序2 - 按下 Enter3 - 主窗口失去焦点4 - 当我点击主窗口时,会发出蜂鸣声,就好像存在模态 MessageBox 一样5 - 要么按下 Escape...重新获得焦点,要么按下 Alt 键,然后 MessageBox 就会以按下 alt 键的方式出现(即菜单将弹出)!!!! - Dr. Mina Mounir
可能是同样的问题,也许是我的系统有问题。我正在使用 Windows 7 x64 编译程序为 32 位时出现了问题!! - Dr. Mina Mounir
@Ramilol 哦,我刚刚找到了解决方案并添加了答案,感谢你的努力...如果您有任何评论,请告诉我。 - Dr. Mina Mounir

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接