2014-06-09 3 views
0

Я пытаюсь реализовать диалог close-save-file в проекте Win32, но возникает странная проблема. Вот мое решение.MessageBox возвращается без ввода пользователем?

  1. Создайте простой проект win32 в Visual Studio.

  2. Обращение WM_COMMAND для создания нового окна.


case WM_COMMAND: 
    wmId = LOWORD(wParam); 
    wmEvent = HIWORD(wParam); 
    // Parse the menu selections: 
    switch (wmId) 
    { 
    case IDM_ABOUT: 
     InitInstance(hInst, SW_SHOW); 
     //DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); 
     break; 
    case IDM_EXIT: 
     windowCount--; 
     DestroyWindow(hWnd); 
     break; 
    default: 
     return DefWindowProc(hWnd, message, wParam, lParam); 
    } 
    break; 
  1. Ручка WM_SYSCOMMNAD, чтобы показать себя, перед тем, бросить MessageBox.

    case WM_SYSCOMMAND: 
     if (wParam == SC_CLOSE) { 
      int ret = MessageBox(NULL, L"do you really want to close", L"question", MB_YESNO|MB_APPLMODAL); 
      if (ret == IDNO) 
       return 0; 
      closedCount++; 
      StringCchPrintf(buff, 256, L"hwnd %x user choose to close\n", hWnd); 
      OutputDebugString(buff); 
     } 
     return DefWindowProc(hWnd, message, wParam, lParam); 
  1. две переменной closeCount и windowCount для обеспечения прекращается после того, как все окна закрыты.


// Main message loop: 
while (GetMessage(&msg, NULL, 0, 0) || (closedCount != windowCount)) 
{ 
    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
} 

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 
{ 
    HWND hWnd; 

    hInst = hInstance; // Store instance handle in our global variable 

    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, 
     CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); 

    if (!hWnd) 
    { 
     return FALSE; 
    } 

    windowCount++; 
    ShowWindow(hWnd, nCmdShow); 
    UpdateWindow(hWnd); 

    return TRUE; 
} 

Полный код: http://pastebin.com/EVWWMz8L

Есть две ошибки в коде выше:

  1. Создать два окна и нажмите кнопку закрытия для каждого окна, а затем подтвердить, чтобы закрыть в течение одного окна закроет оба окна. Это означает, что закрыть MessageBox в одном окне приведет к тому, что MessageBox в другом окне будет возвращаться без ввода пользователем.

  2. Создайте два окна и нажмите кнопку закрытия для каждого окна. Затем используйте aero thumbnail, чтобы активировать одно сообщение и подтвердить, чтобы закрыть, но соответствующее окно не будет закрыто. Мне нужно подтвердить оба окна сообщений, чтобы закрыть окно.

Как это могло случиться, что случилось с моим кодом?

ответ

0

1, Обработчик WM_DESTROY неправильно, правильно обработчик должен быть:

case WM_DESTROY: { 
    StringCchPrintf(buff, 256, L"%x recieved Wm-DESTROY\n", hWnd); 
    OutputDebugString(buff); 
    closedCount++; 
    if (closedCount == windowCount) { 
     PostQuitMessage(0); 
    } 
}

ПОЛНЫЙ код: http://pastebin.com/EU7cVKUb

первопричины:
PostQuitMessage завершить цикл обработки сообщений MessageBox/DialogBox, потому что они отсутствует и немедленно вернуться. В заключение НЕ ЗНАЙТЕ PostQuitMessage, пока вам действительно не нужно это делать.

2, MessageBox/DialogBox должен иметь окно владельца, иначе пользователь может использовать alt + tab/aero-thumbnail, чтобы выбрать поле. Таким образом, создайте ящик сообщений с помощью hwnd, поскольку родитель может решить проблему 2.

Смежные вопросы