防止数据丢失的简单解决方案是添加
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) ...