|
|
Home » Community » Newbie corner » [SOLVED] WIN32 API "MoveFile" and LineEdit Ctrl issue
[SOLVED] WIN32 API "MoveFile" and LineEdit Ctrl issue [message #37856] |
Mon, 19 November 2012 06:32 |
navi
Messages: 107 Registered: February 2012 Location: Sydney, Australia
|
Experienced Member |
|
|
Objective: Trying to batch rename files.
Problem: WIN32 API "MoveFile" fails to rename files if the file names are fetched from LineEdit Ctrl.
My guess is it has got something to do with hidden end of line char or CHARSET Unicode Ascii conversion issue. But I did not yet find a way to fix the problem. It is essential that I fetch the file name from the LineEdit Ctrl. Where the LineEdit Ctrl has multiple lines and each line is a file name.
I have coded a sample program to replicate the problem. Attached are the codes and screen-shots.
Thanks,
Navi
Reference:
MoveFile function (Windows) [MSDN]
System Error Codes (0-499) (Windows) [MSDN]
#include <CtrlLib/CtrlLib.h>
#include <CtrlCore/CtrlCore.h>
using namespace Upp;
GUI_APP_MAIN
{
TopWindow w;
LineEdit e,f;
Vector<String> v1, v2; // Vectors for Storing File Names
String s; // String for temporary use
bool r=false; // r to keep the "MoveFile" API Return
int err_no=0; // err_no to keep "GetLastError" API Return
// GUI SETUP CODE
e.SetRect(10,10,680,100);
f.SetRect(10,120,680,220);
w.SetRect(0,0,700,350);
w<<e<<f;
// ADDING SOME DUMMY BUT VALID FILE NAMES THAT DO EXIST
v1.Add("E:\\TEMP\\1.txt");
v1.Add("E:\\TEMP\\2.txt");
v1.Add("E:\\TEMP\\3.txt");
// CATENATING VECTOR 'v1' INOT TEMP STRING 's' TO LOAD ALL FILE NAMEs INTO LINEEDIT
for(int i=0; i<v1.GetCount(); i++){
s<<v1[i]<<"\n";
}
e.Set(s);
// FETCHING THE FILE NAME BACK FROM THE LINEEDIT AND SPLITTING THEM INTO SEPERATE STRING
s.Clear();
s=e.Get();
v2=Split(s, "\n", true);
// TEST-1: RENAMEING FILES USING v1 FILE NAME TO v1 FILE NAME (Ya Same Names. for tests only!)
s.Clear();
s<<"DEBUG INFO: TEST-1:\n";
for(int i=0; i<v1.GetCount(); i++){
r=MoveFile(v1[i],v1[i]);
(!r)? err_no=GetLastError() : err_no=0;
s<<"RENAME "
<<v1[i]<<" => "<<v1[i]
<<" [Done="<<r<<"] [Error="
<<err_no<<"]\n";
}
// TEST-2: RENAMEING FILES USING v1 FILE NAME TO v2 FILE NAME (Ya Same Names. but from LineEdit Ctrl)
s<<"\nDEBUG INFO: TEST-2:\n";
for(int i=0; i<v1.GetCount(); i++){
r=MoveFile(v1[i],v2[i]);
(!r)? err_no=GetLastError() : err_no=0;
s<<"RENAME "
<<v1[i]<<" => "<<v2[i]
<<" [Done="<<r<<"] [Error="
<<err_no<<"]\n";
}
s<<"\n***Error Code 123(0x7B) = ERROR_INVALID_NAME\n";
// PRINTING THE RESULTS
f.Set(s);
// Executing the Window
w.Run();
}
-
Attachment: main.cpp
(Size: 1.79KB, Downloaded 258 times)
[Updated on: Mon, 19 November 2012 13:51] Report message to a moderator
|
|
|
|
|
Re: WIN32 API "MoveFile" and LineEdit Ctrl issue [message #37860 is a reply to message #37858] |
Mon, 19 November 2012 08:23 |
|
Hello Navi,
The problem is not with U++ but how you use WINAPI.
Quote: | lpNewFileName [in]
The new name for the file or directory. The new name must not already exist. A new file may be on a different file system or drive. A new directory must be on the same drive.
|
What are you trying to do is exactly what this API call doesn't allow. It should work if you choose a new name for files.
Best regards,
Andrei
|
|
|
|
|
|
|
|
|
|
|
Re: WIN32 API "MoveFile" and LineEdit Ctrl issue [message #37873 is a reply to message #37872] |
Mon, 19 November 2012 13:50 |
navi
Messages: 107 Registered: February 2012 Location: Sydney, Australia
|
Experienced Member |
|
|
Hello Deep and Koldo,
First of all let me congratulate and thank you guys for great detective investigation. Deep, great technique for investigating strings. I also solve it by myself but was a bit late to reply. But I found the solution and the cause of the problem by chance. Since, unlike Deep I could not figure how to look inside the string, I assume the string has something invisible and started to write my very own splitter. char by char. While doing that I stumble upon the issue that it's not that easy to split where '\n' is the delimiter. Upon searching the forum I stumble upon the following post by "great" Mirek: which essentially explains the problem and provides a elegant solution. Applying his Filter() solution I got it working immediately.
http://www.ultimatepp.org/forum/index.php?t=msg&goto=104 91&
mirek wrote on Tue, 10 July 2007 23:26 | Well, it is not U++, it is M$... Back in MSDOS days, they have decided that line are to be ended with "\r\n" and this stupid idea is still alive.
Standard C library solves this problem by intruducing "text" and "binary" streams (text streams remove/insert \r on read/write), but IMO that just adds to confusion.
U++ general take on the problem is to ignore all \r characters on input and insert \r before each \n on output - but both is to be handled by the code.
In your case you have many options. One simple is to filter out all \r out before Split:
int NoCr(int c) { return c == '\r' ? 0 : c; }
Split(Filter(s, NoCr), '\n')
As you seem to ignore empty lines, another simple solution (with a bit better performance) is to treat \r like \n (because it will just result in empty line, which is ignored anyway):
int CrOrLf(int c) { return c == '\r' || c == '\n' ? c : 0; }
Split(s, CrOrLf);
Mirek
|
Screen Shot of the Program applying Mirek's Filter() Solution.
Thank you very much for your help guys. I really appreciate it.
Navi
-
Attachment: pic3.png
(Size: 71.21KB, Downloaded 829 times)
[Updated on: Mon, 19 November 2012 14:26] Report message to a moderator
|
|
|
Goto Forum:
Current Time: Wed Jun 05 06:06:30 CEST 2024
Total time taken to generate the page: 0.02403 seconds
|
|
|