2013-05-01 62 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; 
} 
相关问题