2014-06-09 3 views
0

닫기 저장 파일 대화 상자를 Win32 프로젝트에 구현하려하지만 이상한 문제가 발생합니다. 여기 내 해결책이있다.사용자 입력없이 MessageBox가 반환됩니까?

  1. Visual Studio에서 간단한 win32 프로젝트를 만듭니다.

  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

    는 저장-전에-종료 메시지 박스를 표시합니다. 모든 창을 닫은 후 종료 보장하기 closeCountwindowCount 변수

    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. 이.


// 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. 두 개의 창을 만들고 각 창에 대해 닫기 단추를 클릭하십시오. 그런 다음 에어로 축소판을 사용하여 하나의 메시지 상자를 활성화하고 닫으려면 확인하지만 연결된 창은 닫히지 않습니다. 메시지 상자를 닫으려면 두 메시지 상자를 모두 확인해야합니다.

어떻게 내 코드가 잘못 되었나요?

답변

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

FULL 코드 : http://pastebin.com/EU7cVKUb

근본 원인 :
PostQuitMessage이 그 원인, 메시지 박스/대화 상자 메시지 루프를 종료 누락되어 즉시 반환됩니다. 결론적으로, 실제로 이것을 할 필요가있을 때까지 PostQuitMessage를 호출하지 마십시오.

2, MessageBox/DialogBox에는 소유자 창이 있어야하며, 그렇지 않으면 alt + tab/aero-thumbnail을 사용하여 상자를 선택할 수 있습니다. 그래서 부모가 문제 2를 해결할 수있는 hwnd로 messagebox를 만드십시오.

관련 문제