从 OPENFILENAME win32 中的 SAVE 按钮移除焦点?
Remove focus from SAVE button in OPENFILENAME win32?
问题:
如果用户按住“输入”键盘按钮并打开 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[=10=]*.*[=10=]Text[=10=]*.TXT[=10=]");
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetSaveFileName(&ofn) == TRUE)
{
// file saved
}
可能的解决方案:
- 当ofn.lpstrFile为空时什么都不做;无法保存文件
没有文件名
- 当 ofn.lpstrFile 建议文件名时,关闭对“保存”按钮的关注或以某种方式忽略按钮输入按住。
我尝试这样做但失败了,我是 CPP 的初学者 :(
感谢帮助
防止数据丢失的简单解决方案是添加 OFN_OVERWRITEPROMPT
标志。如果建议的名称作为文件尚不存在,这不会阻止问题的发生。
要与对话框实际交互,您需要 OFN_ENABLEHOOK
和一个挂钩函数。当您收到 WM_NOTIFY
时,如果时间不够,您可以处理 CDN_FILEOK
以阻止建议的名称,或者可以更改 CDN_INITDONE
中的焦点。
无论哪种方式,您都必须注意,您正在改变通用对话框的工作方式,这可能会激怒一些用户。
这是一种方法。 return 对话正常的实际延迟是您必须自己决定的事情。
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) ...
问题:
如果用户按住“输入”键盘按钮并打开 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[=10=]*.*[=10=]Text[=10=]*.TXT[=10=]");
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetSaveFileName(&ofn) == TRUE)
{
// file saved
}
可能的解决方案:
- 当ofn.lpstrFile为空时什么都不做;无法保存文件 没有文件名
- 当 ofn.lpstrFile 建议文件名时,关闭对“保存”按钮的关注或以某种方式忽略按钮输入按住。
我尝试这样做但失败了,我是 CPP 的初学者 :(
感谢帮助
防止数据丢失的简单解决方案是添加 OFN_OVERWRITEPROMPT
标志。如果建议的名称作为文件尚不存在,这不会阻止问题的发生。
要与对话框实际交互,您需要 OFN_ENABLEHOOK
和一个挂钩函数。当您收到 WM_NOTIFY
时,如果时间不够,您可以处理 CDN_FILEOK
以阻止建议的名称,或者可以更改 CDN_INITDONE
中的焦点。
无论哪种方式,您都必须注意,您正在改变通用对话框的工作方式,这可能会激怒一些用户。
这是一种方法。 return 对话正常的实际延迟是您必须自己决定的事情。
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) ...