Win32 MessageBox не появляется - PullRequest
5 голосов
/ 29 ноября 2010

Я застрял со странной проблемой. Я делаю приложение Win32 в VC ++ 2008, создавая класс для инкапсуляции большей части работы для легкого повторения при вызове MessageBox. Окно сообщения `создается (я думаю), но не отображается, пока я не нажму клавишу Alt!

Что именно происходит:

  1. Я запускаю программу

  2. нажмите Enter

  3. главное окно теряет фокус

  4. издает звуковой сигнал при нажатии на главное окно, как будто присутствует модальный MessageBox

  5. либо нажмите Escape ... фокус получен ИЛИ нажмите Alt, затем появится MessageBox с нажатой клавишей alt (т.е. меню упадет) !!!!!!

P.S. Это работало нормально, но вдруг это случилось. Я не нашел никакой разницы - я даже сделал новый проект!

Предполагается, что основная программа:

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;
};

P.S. Я включил все необходимые заголовочные файлы, все идет хорошо, кроме MessageBox

Это также ссылка на код здесь

Ответы [ 4 ]

9 голосов
/ 29 ноября 2010

Охххххххх, наконец-то я нашел решение этой проблемы ... и для всех в пользу проблемы была в WndProc (.......) в сообщении WM_PAINT я написал некоторый код в нем и удалил весь код вместес функциями BeginPaint и EndPaint, поэтому программа вводит период замораживания, когда поверх него закрашивается что-либо, включая этот MessageBox, но он отображается только при нажатии Alt, я думаю, потому что элемент управления передается системе на этом шаге для отображения системного меню (яподумайте)

решение либо удалите обработчик сообщений WM_PAINT, либо добавьте обычные функции BeginPaint и EndPaint

Спасибо всем, кто ответил на мой вопрос

4 голосов
/ 09 апреля 2013

Если кому-то все еще интересно, этот метод работает:

MessageBox(NULL,L"error",L"Error",MB_ICONERROR|MB_DEFAULT_DESKTOP_ONLY);
3 голосов
/ 31 октября 2014

У меня была похожая проблема, которая была вызвана WM_PAINT, как кто-то выше упомянул. Решил, добавив туда return DefWindowProc(hWnd, Message, wParam, lParam);.

2 голосов
/ 29 ноября 2010

Когда вы создаете свой MessageBox, вы должны передать WS_CHILD в CreateWindowEx.
EDIT 2:
Хорошо, попробуйте это.

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