使用GetOpenFileName获取文件路径后,CopyFile API函数无法正常工作

时间:2017-04-01 20:54:00

标签: c++ winapi c++builder c++builder-6

我使用GetOpenFileName()获取文件路径,然后使用CopyFile()将文件复制到具有不同文件名的同一目录。

使用GetLastError(),我收到错误代码:

  

0x2 - 系统找不到指定的文件。

但是当我使用MessageBox()查看文件名时,它显示了正确的文件名。

除此之外,我还尝试了StrTrim()文件名,但它仍无效。

我正在使用Borland C ++ Builder 6.0。

CODE

OPENFILENAME ofn;
char szFile[260];
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner =  Form1->Handle;
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "All\0*.*\0Text\0*.txt\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = 0;
GetOpenFileName(&ofn);

LPSTR FileName;
FileName = ofn.lpstrFile;
MessageBox (Form1->Handle, FileName, "File Name", MB_OK);
MessageBox (Form1->Handle, strcat(FileName, ".newfile"), "New File Name", MB_OK);
CopyFile(FileName, strcat(FileName,".newfile"), false);

已编辑的代码

我尝试过使用两个变量,但它仍然无效。有人可以建议改正吗?

LPSTR FileName;
LPSTR NewFileName;
FileName = ofn.lpstrFile;
NewFileName = FileName;
strcat(NewFileName, ".newfile");
MessageBox (Form1->Handle, FileName, "File Name", MB_OK);
MessageBox (Form1->Handle, NewFileName, "New File Name", MB_OK);
CopyFile(FileName, NewFileName, false);

工作代码

以下代码有效,但我必须添加一个文本框/编辑控件。有没有办法在不增加额外控制的情况下做到这一点?

LPSTR FileName;
AnsiString NewFileName;
FileName = ofn.lpstrFile;
Edit1->Text = FileName;
NewFileName = Edit1->Text + ".bak";
MessageBox (Form1->Handle, FileName, "File Name", MB_OK);
MessageBox (Form1->Handle, NewFileName.c_str(), "New File Name", MB_OK);

1 个答案:

答案 0 :(得分:4)

您正在为CopyFile()的两个参数使用单个缓冲区,并且您要将新扩展名附加到该缓冲区,因此CopyFile()当然不会找到要复制的文件。

您需要为CopyFile()的两个参数使用两个单独的缓冲区,例如:

TCHAR szSrcFile[MAX_PATH];
TCHAR szDstFile[MAX_PATH+12];

OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = Form1->Handle;
ofn.lpstrFile = szSrcFile;
ofn.lpstrFile[0] = TEXT('\0');
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFilter = TEXT("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 (GetOpenFileName(&ofn))
{    
    lstrcpy(szDstFile, szSrcFile);
    lstrcat(szDstFile, TEXT(".newfile"));
    MessageBox(Form1->Handle, szSrcFile, TEXT("File Name"), MB_OK);    
    MessageBox(Form1->Handle, szDstFile, TEXT("New File Name"), MB_OK);
    CopyFile(szSrcFile, szDstFile, FALSE);
 }

话虽如此,由于您使用的是Borland的VCL框架,您应该直接使用TOpenDialog组件而不是GetOpenFileName(),然后您可以使用String变量来轻松连接:< / p>

// these properties can also be set at design-time instead...
OpenDialog1->Filter = "All|*.*|Text|*.txt";
OpenDialog1->FilterIndex = 1;
OpenDialog1->Options = TOpenOptions() << ofPathMustExist << ofFileMustExist;

if (OpenDialog1->Execute())
{
    String SrcFile = OpenDialog1->FileName;
    String DstFile = SrcFile + ".newfile";
    CopyFileA(SrcFile.c_str(), DstFile.c_str(), FALSE);
}