2013-05-01 57 views
1

此代碼生成簡單的FindText對話框窗口,當用戶單擊右上角的X窗口關閉按鈕時,WM_CLOSE消息將發送到掛鉤過程,但當單擊「取消「按鈕沒有消息產生,以表明該窗口不再。如何確定當用戶單擊「取消」時關閉FindText對話框

#include <windows.h> 
#include <iostream> 
#include <iomanip> 

UINT_PTR CALLBACK FRHookProc(HWND hdlg, UINT uiMsg, WPARAM /*wParam*/, LPARAM /*lParam*/) { 
    switch (uiMsg) { 
    case WM_INITDIALOG: { 
     ShowWindow(hdlg, SW_SHOW); 
     break; 
    } 
    } 
    using namespace std; 
    if (uiMsg == WM_CLOSE) cout << "FindTextW window has been closed"; 
    return 0; 
} 

LRESULT CALLBACK MyWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) 
{ 
    return DefWindowProcW(hWnd, Msg, wParam, lParam); 
} 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int /* nCmdShow*/) { 
    using namespace std; 

    WNDCLASSEXW wc; 
    wc.cbSize = sizeof(WNDCLASSEXW); 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = &MyWndProc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = sizeof(PVOID); 
    wc.hInstance = hInstance; 
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
    wc.hIconSm = NULL; 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BACKGROUND); 
    wc.lpszMenuName = L"MainMenu"; 
    wc.lpszClassName = L"window"; 
    ATOM class_atom = RegisterClassExW(&wc); 

    HWND hWnd = CreateWindowExW(
    0, 
    reinterpret_cast<LPCWSTR>(class_atom), 
    L"window title", 
    WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPCHILDREN | WS_THICKFRAME, 
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
    NULL, 
    NULL, 
    hInstance, 
    NULL 
); 

    WCHAR szFindWhat[MAX_PATH] = {0}; 

    FINDREPLACEW fr; 
    ZeroMemory(&fr, sizeof(fr)); 
    fr.lStructSize = sizeof(fr); 
    fr.hwndOwner = hWnd; 
    fr.lpstrFindWhat = szFindWhat; 
    fr.lpfnHook = FRHookProc; 
    fr.wFindWhatLen = MAX_PATH; 
    fr.Flags = FR_ENABLEHOOK; 
    /*HWND hdlg =*/ FindTextW(&fr); 

    MSG msg; 
    for (;;) { 
    GetMessageW(&msg, 0, 0, 0); 
    TranslateMessage(&msg); 
    DispatchMessageW(&msg); 
    } 
    return 0; 
} 
+0

也許我錯了,但WM_DESTROY不發? – Xearinox 2013-05-01 19:31:17

回答

2

Read the documentation更仔細。你採取了完全錯誤的方法來檢測正在關閉的對話窗口。

FindText function

在致電FINDTEXT,你必須調用RegisterWindowMessage函數得到了FINDMSGSTRING消息中的標識。對話框過程使用此標識符在用戶單擊「查找下一個」按鈕時發送消息,或在對話框關閉時彈出

FINDMSGSTRING message

甲查找或替換對話框發送註冊消息其所有者窗口當用戶點擊查找下一個,替換,或全部替換按鈕的窗口過程的FINDMSGSTRING,或關閉對話框

...

您必須指定到RegisterWindowMessage函數調用的FINDMSGSTRING不斷獲得由對話框發送消息的標識符。

當您創建對話框時,使用FINDREPLACE結構的hwndOwner成員來標識接收FINDMSGSTRING消息的窗口

...

的FINDREPLACE結構的Flags構件包括以下標誌,以指示所造成的消息的事件中的一個。

FR_DIALOGTERM(0x00000040) 該對話框正在關閉。所有者窗口處理完此消息後,該對話框的句柄不再有效。

因此,隨着中說,試試這個來代替:

#include <windows.h> 
#include <iostream> 
#include <iomanip> 

static const UINT uFindMsgString = RegisterWindowMessageW(L"commdlg_FindReplace"); 

LRESULT CALLBACK MyWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) 
{ 
    if ((Msg == uFindMsgString) && (Msg != 0)) 
    { 
    FINDREPLACE *fr = reinterpret_cast<FINDREPLACE*>(lParam); 
    if (fr->flags & FR_DIALOGTERM) 
    { 
     std::cout << "FindTextW window has been closed"; 
     PostQuitMessage(0); 
    } 

    // process other dialog notifications as needed... 

    return 0; 
    } 

    return DefWindowProcW(hWnd, Msg, wParam, lParam); 
} 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int /* nCmdShow*/) 
{ 
    WNDCLASSEXW wc = {0}; 
    wc.cbSize = sizeof(WNDCLASSEXW); 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = &MyWndProc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = sizeof(PVOID); 
    wc.hInstance = hInstance; 
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
    wc.hIconSm = NULL; 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BACKGROUND); 
    wc.lpszMenuName = L"MainMenu"; 
    wc.lpszClassName = L"window"; 

    ATOM class_atom = RegisterClassExW(&wc); 

    HWND hWnd = CreateWindowExW(
    0, 
    wc.lpszClassName, 
    L"window title", 
    WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPCHILDREN | WS_THICKFRAME, 
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
    NULL, 
    NULL, 
    hInstance, 
    NULL 
); 

    WCHAR szFindWhat[MAX_PATH] = {0}; 

    FINDREPLACEW fr = {0}; 
    fr.lStructSize = sizeof(fr); 
    fr.hwndOwner = hWnd; 
    fr.lpstrFindWhat = szFindWhat; 
    fr.wFindWhatLen = MAX_PATH; 

    HWND hdlg = FindTextW(&fr); 

    MSG msg; 
    while (GetMessageW(&msg, 0, 0, 0) > 0) 
    { 
    if (!IsDialogMessage(hdlg, &msg)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessageW(&msg); 
    } 
    } 

    DestroyWindow(hWnd); 
    UnregisterClass(wc.lpszClassName, hInstance); 

    return 0; 
} 
相關問題