代码之家  ›  专栏  ›  技术社区  ›  Maciej Pulikowski

是否从OPENFILENAME win32中的“保存”按钮中删除焦点?

  •  0
  • Maciej Pulikowski  · 技术社区  · 2 年前

    问题:

    如果用户按住“回车”键盘按钮并打开OPENFILENAME另存为对话框,它将自动保存文件-对话框只会闪烁。

    预期结果:

    用户按住“回车”键,打开OPENFILENAME另存为对话框, 什么都没发生 。他需要单击“保存”按钮或再次单击“输入”键盘按钮来保存文件。

    我当前的代码:

    OPENFILENAME ofn;
    TCHAR szFile[260] = { 't','e','s','t'}; // example filename
    
    // Initialize OPENFILENAME
    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = hWnd;    
    ofn.lpstrFile = szFile;
    ofn.nMaxFile = sizeof(szFile);
    //Files like: (ALL - *.*), (Text - .TXT)
    ofn.lpstrFilter = _T("All\0*.*\0Text\0*.TXT\0");
    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = NULL;
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    
    if (GetSaveFileName(&ofn) == TRUE)
    {
        // file saved
    }
    

    Actual dialog

    可能的解决方案:

    • 当我离开的时候。lpstrFile为空,不做任何事情;存在时无法保存文件 没有文件名
    • 当我离开的时候。lpstrFile已建议文件名,然后关闭“保存”按钮上的焦点,或以某种方式忽略按钮输入保持。

    我试着这么做但失败了, 我是CPP的初学者 :(

    谢谢你的帮助

    0 回复  |  直到 2 年前
        1
  •  2
  •   Anders    2 年前

    防止数据丢失的简单解决方案是添加 OFN_OVERWRITEPROMPT 旗帜如果建议的名称尚未作为文件存在,则这不会阻止问题的发生。

    真正与你需要的对话互动 OFN_ENABLEHOOK 还有一个钩子函数。当你收到 WM_NOTIFY ,你能处理 CDN_FILEOK 如果没有足够的时间,或者可能会更改中的焦点,则阻止建议的名称 CDN_INITDONE .

    不管是哪种方式,你都必须注意,你正在改变一个普通对话框的工作方式,这可能会激怒一些用户。

    这里有一种方法。让对话恢复正常的实际延迟是你必须自己决定的。

    const int btnid = 1337;
    
    void CALLBACK resetsavedlgdefpush(HWND hWnd, UINT Msg, UINT_PTR idEvent, DWORD Time)
    {
        KillTimer(hWnd, idEvent);
        HWND hDlg = GetParent(hWnd);
        UINT id = LOWORD(SendMessage(hDlg, DM_GETDEFID, 0, 0));
        if (id == btnid)
        {
            SendMessage(hDlg, DM_SETDEFID, IDOK, 0);
        }
    }
    
    UINT_PTR CALLBACK mysavehook(HWND hWndInner, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
        if (Msg == WM_NOTIFY)
        {
            OFNOTIFY*pOFN = (OFNOTIFY*) lParam;
            if (pOFN->hdr.code == CDN_INITDONE)
            {
                HWND hDlg = GetParent(hWndInner);
                CreateWindowEx(0, TEXT("BUTTON"), 0, BS_DEFPUSHBUTTON|BS_TEXT|WS_CHILD|WS_VISIBLE, 0, 0, 0, 0, hWndInner, (HMENU) btnid, 0, 0);
                SendMessage(hDlg, DM_SETDEFID, btnid, 0);
                PostMessage(hDlg, DM_SETDEFID, btnid, 0);
                int keydelay = 0;
                SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &keydelay, 0);
                SetTimer(hWndInner, 0, (250 * ++keydelay) * 5, resetsavedlgdefpush);
            }
        }
        return 0;
    }
    
    ...
    ofn.Flags = OFN_PATHMUSTEXIST|OFN_EXPLORER|OFN_OVERWRITEPROMPT|OFN_ENABLESIZING|OFN_ENABLEHOOK;
    ofn.lpfnHook = mysavehook;
    MessageBox(ofn.hwndOwner, TEXT("Hold enter to test..."), 0, 0);
    if (GetSaveFileName(&ofn) == TRUE) ...