我正在使用GetOpenFileName
并将lpstrInitialDir
结构的OPENFILENAME
成员设置为我想要的目录作为初始目录。但是在Win7上我的应用程序似乎记得用户上次打开的目录,它忽略lpstrInitialDir
设置并转到最后一个目录。
lpstrInitialDir
LPCTSTR
初始目录。 选择初始目录的算法在不同平台上有所不同。Windows 7:
1.如果lpstrInitialDir具有与第一次传递的值相同的值 应用程序使用Open或Save As 对话框,最近的路径 由用户选择用作 初始目录。
2.否则,如果lpstrFile包含路径,则该路径是初始路径 目录。
3.否则,如果lpstrInitialDir不为NULL,则指定初始值 。目录
有谁知道如何阻止这种情况发生?
我希望我指定的目录是初始目录,而不管用户上次打开的文件是什么,即我希望上面的条件3适用。我做了显而易见的事情并通过注册表进行了搜索,但我找不到任何与此问题相关的内容。
答案 0 :(得分:1)
如果将lpstrFile
设置为所需的初始目录路径(即lpstrInitialDir
),会发生什么。如果使用lpstrFile
指定文件名,则可能需要在文件名前添加初始目录路径。
答案 1 :(得分:1)
我知道这个帖子很旧,但我最近遇到了这个问题,我找到了解决方案。 GetOpenFileName() 将上次使用的路径保存在注册表中。路径是: HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\
有两个键,我不确定实际使用哪个以及在什么情况下使用,但我从两个键中删除了我的应用程序条目。两个键是: “LastVisitedPidlMRU”和“LastVisitedPidlMRULegacy”。
应用程序名称保存为具有 16 位字符编码的 RegBinary 值(这就是它不会出现在注册表搜索中的原因...)。 我想出了以下函数来删除注册表项,从而迫使 Windows 相信我的应用程序以前从未调用过 GetOpenFileName():
void clear_path_in_registry ()
{
char keypath[PATH_MAX];
char *keys[] = { "LastVisitedPidlMRU", "LastVisitedPidlMRULegacy" };
#define NO_OF_KEYS (sizeof(keys)/sizeof(*keys))
int keynr;
HKEY hkey;
int res;
char val_data[BUFLEN];
DWORD val_len, data_len;
int i;
char val_name[VALUELEN];
char progname[PATH_MAX];
char *p, *q;
char exename[PATH_MAX];
int index;
int *pi , *pj;
do_debug (1, "clear_path_in_registry()\n");
GetModuleFileName (NULL, progname, sizeof(progname));
p = strrchr (progname, '\\');
if (p)
p ++;
strncpy (exename, p, sizeof(exename)-1);
keynr = 0;
do
{
snprintf (keypath, sizeof(keypath),
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\%s",
keys[keynr]);
res = RegOpenKeyEx (HKEY_CURRENT_USER,keypath,0,KEY_ALL_ACCESS,&hkey);
if (res == ERROR_SUCCESS)
{
i = 0;
val_len = sizeof (val_name);
data_len = sizeof (val_data);
while (RegEnumValue(
hkey,i,val_name,&val_len,NULL,NULL,(BYTE *)val_data,&data_len)
== ERROR_SUCCESS)
{
if (stricmp(val_name, "MRUListEx"))
{
/* is not the "MRUListEx" value -> extract program name
*
* for some (unknown) reason the program names are not stored as
* RegSZ but rather as RegBinary values. They are encoded in some
* dual-byte encoding. In my experiments the high bytes are
* always 0x00; so the transcoding is simple, just skip the high
* bytes. Probably there is a WIN32 API call for this but I did
* dig into that for now ...
*/
p = progname;
q = val_data;
while (*q)
{
*p++ = *q++;
q ++;
}
*p = '\0';
/* the index in the MRUList is the value name */
index = atoi (val_name);
if (stricmp (progname, exename) == 0)
{
/* found the value with current executable name -> delete it */
res = RegDeleteValue (hkey, val_name);
if (res == ERROR_SUCCESS)
{
/* delete the entry from the MRUList
*
* The MRUListEx value is a of the type RegBinary as well.
* The data structure is fairly simple: just 4-byte integers
* one after the other; -1 marks the end of the list
*/
data_len = sizeof (val_data);
res = RegQueryValueEx (hkey, "MRUListEx", NULL, NULL,
(BYTE*)val_data, &data_len);
if (res == ERROR_SUCCESS)
{
pi = (int *)val_data;
pj = (int *)val_data;
while (*pj != -1)
{
if (*pj == index)
{
pj ++;
data_len -= sizeof(int);
}
*pi++ = *pj++;
}
*pi = *pj;
res = RegSetValueEx (hkey, "MRUListEx", 0, REG_BINARY,
(BYTE *)val_data, data_len);
if (res != ERROR_SUCCESS)
{
do_debug (1,"ERROR writing registry value 'MRUListEx'\n");
}
} else
{
do_debug (1, "ERROR reading registry value 'MRUListEx'\n");
}
} else
{
do_debug (1,"ERROR deleting registry value '%s'\n",val_name);
}
}
}
val_len = sizeof (val_name);
data_len = sizeof (val_data);
i ++;
} /* iterate through registry values */
}
res = RegCloseKey (hkey);
if (res != ERROR_SUCCESS)
{
do_debug (1, "Error closing registry key '%s'\n", keys[keynr]);
}
keynr ++;
} while (keynr < NO_OF_KEYS);
}
只需在调用 GetOpenFileName() 之前调用此函数即可。
我在 Windows 10 版本 19042.1052,64 位上进行了测试。
约翰内斯