C++ - Having problems with a simple example of FindFirstFile - c++

I'm using the following ultra-super-mega simple code to list all the files in a direcory (Windows 8.1, Visual Studio Express 2013, C++):
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <limits>
#include <cstdio>
#include <iostream>
#include <fstream>
#include <bitset>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
using namespace std;
void get_file_list(string DATA_DIR)
{
HANDLE hFind;
WIN32_FIND_DATA data;
hFind = FindFirstFile(LPCWSTR(DATA_DIR.c_str()), &data);
if (hFind != INVALID_HANDLE_VALUE) {
do {
printf("%s\n", data.cFileName);
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
}
int main(int argc, char** argv)
{
string DATA_DIR = "D:\\drobpox\\Dropbox\\BinaryDescriptors\\LFW\\DATA\\*.*";
//string DATA_DIR = "c:\\Users\\GilLevi\\Downloads\\GraphsSURF\\GraphsSURF\\bark\\*.jpg";
string OUT_DIR = "D:\\drobpox\\Dropbox\\BinaryDescriptors\\LFW\\LATCH_TXT_FILES\\LATCH8";
get_file_list(DATA_DIR);
}
However, I "hFind" always equals "INVALID_HANDLE_VALUE". I double checked the path and tried various different paths.
Might the reason be that I'm running a 64bit application and using WIN32_FIND_DATA ?
Thanks in advance,
Gil

Converting a string to a widestring requires you to allocate memory and use string conversion functions.
If you don't want to change the function, the easiest solution is probably to use the non-unicode version of FindFirstFile, by Adding a A to the functionname and struct;
WIN32_FIND_DATAA data;
hFind = FindFirstFileA(DATA_DIR.c_str(), &data);

Since you're using LPCWSTR, you should be using std::wstring, not std::string in your program.
Also, there is no conversion magic when you cast to an LPCWSTR. It is just a dumb 'C' cast that basically does nothing except shut the compiler up.

Related

AnsiString does not work (AnsiString identifier is not defined)

Here's the code:
AnsiString path = "BrowserBot.exe";
ShellExecute(0, TEXT("open"), path.c_str(), TEXT("-parametr"), 0, SW_SHOW);
Writes an error that the AnsiString identifier is not defined. I don't know what the problem is.
All connected libraries:
#include <iostream>
#include <conio.h>
#include <Windows.h>
#include <fstream>
#include <sstream>
AnsiString is a string class that is specific to the C++Builder compiler. If you are using that compiler, make sure you are compiling your project with C++Builder's VCL (Visual Component Library) or FMX (FireMonkey) framework enabled, and that you have a corresponding #include <vcl.h> or #include <fmx.h> statement in your C++ code.
Otherwise, if you are using any other compiler, you should use the standard C++ std::string class instead (which can also be used in C++Builder), eg:
#include <string>
std::string path = "BrowserBot.exe";
ShellExecuteA(0, "open", path.c_str(), "-parametr", 0, SW_SHOW);

Create Directory and Navigate into Directory c++

I have successfully made a directory in AppData Folder, but i want to navigate into that folder using C++ How do i go about it.
My code looks like this
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main()
{
//printf("Hello world!\n");
char *name = getenv("USERNAME");
char info[1500];
const int bufferSize = MAX_PATH;
sprintf(info,"C:\\Users\\%s\\AppData\\Local\\BizMail", name);
_mkdir(info);
getchar();
return 0;
}
Use chdir() function it works on both POSIX and Windows.
Here is the man page
You can also use SetCurrentDirectory() function. Refer here and here is the sample program.

Unable to call `SetWallpaper()` due to error LNK2019

Intro
First of all, I would like to say that I have read through the previous answers for this type of question, including this excellently written one.
However, I do not understand enough about C++ to be able to use the more "advanced" fixes.
I have ensured that the right type of console has been selected (Console (/SUBSYSTEM:CONSOLE) for those interested), and have the required imports with the possible exception of an IDL mentioned somewhere (that falls into the lack of understanding category).
If this is a duplicate, I would be more than happy to use the post I duplicated, but I have not been able to find anything that can help someone of my skill level.
Technical Information
IDE: Visual Studio
Platform: Windows
Code
headers.h
#pragma once
#include <stdio.h>
#include <iostream>
#include <string>
#include <windows.h>
#include <Shobjidl.h>
#include <time.h>
#include <stdlib.h>
#include <tchar.h>
main.cpp
#include "headers.h"
using namespace std;
int main() {
string x = "C://Users/student/Desktop/i-should-buy-a-boat.jpg";
x.c_str();
wstring tempx = std::wstring(x.begin(), x.end());
LPCWSTR sw = tempx.c_str();
HRESULT SetWallpaper(
LPCWSTR monitorID,
LPCWSTR wallpaper
);
SetWallpaper(NULL, sw);
}
SetWallpaper() is not a standalone function exported by the Win32 API. It is a method of the IDesktopWallpaper interface (see here).
So you need to use code that is more like this instead:
#include "headers.h"
int main()
{
std::wstring x = L"C:\\Users\\student\\Desktop\\i-should-buy-a-boat.jpg";
CoInitialize(NULL);
IDesktopWallpaper *p;
if (SUCCEEDED(CoCreateInstance(__uuidof(DesktopWallpaper), 0, CLSCTX_LOCAL_SERVER, __uuidof(IDesktopWallpaper), (void**)&p)))
{
p->SetWallpaper(NULL, x.c_str());
p->Release();
}
CoUninitialize();
return 0;
}

Converting 'const char*' to 'LPCTSTR' for CreateDirectory

#include "stdafx.h"
#include <string>
#include <windows.h>
using namespace std;
int main()
{
string FilePath = "C:\\Documents and Settings\\whatever";
CreateDirectory(FilePath, NULL);
return 0;
}
Error: error C2664: 'CreateDirectory' : cannot convert parameter 1 from 'const char *' to 'LPCTSTR'
How do I make this conversion?
The next step is to set today's date as a string or char and concatenate it with the filepath. Will this change how I do step 1?
I am terrible at data types and conversions, is there a good explanation for 5 year olds out there?
std::string is a class that holds char-based data. To pass a std::string data to API functions, you have to use its c_str() method to get a char* pointer to the string's actual data.
CreateDirectory() takes a TCHAR* as input. If UNICODE is defined, TCHAR maps to wchar_t, otherwise it maps to char instead. If you need to stick with std::string but do not want to make your code UNICODE-aware, then use CreateDirectoryA() instead, eg:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::string FilePath = "C:\\Documents and Settings\\whatever";
CreateDirectoryA(FilePath.c_str(), NULL);
return 0;
}
To make this code TCHAR-aware, you can do this instead:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::basic_string<TCHAR> FilePath = TEXT("C:\\Documents and Settings\\whatever");
CreateDirectory(FilePath.c_str(), NULL);
return 0;
}
However, Ansi-based OS versions are long dead, everything is Unicode nowadays. TCHAR should not be used in new code anymore:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::wstring FilePath = L"C:\\Documents and Settings\\whatever";
CreateDirectoryW(FilePath.c_str(), NULL);
return 0;
}
If you're not building a Unicode executable, calling c_str() on the std::string will result in a const char* (aka non-Unicode LPCTSTR) that you can pass into CreateDirectory().
The code would look like this:
CreateDirectory(FilePath.c_str(), NULL):
Please note that this will result in a compile error if you're trying to build a Unicode executable.
If you have to append to FilePath I would recommend that you either continue to use std::string or use Microsoft's CString to do the string manipulation as that's less painful that doing it the C way and juggling raw char*. Personally I would use std::string unless you are already in an MFC application that uses CString.

FindFirstFile() show address

I used function FindFirstFile() but i received only memory address - not a file name.
#include <stdafx.h>
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
WIN32_FIND_DATA File_Data;
FindFirstFile(TEXT("C:\\Users\\user\\Desktop\\temp\\*.tmp"), &File_Data);
cout<<File_Data.cFileName;
cin.get();
return 0;
}
Can anybody help me?
You are probably compiling using the Unicode character set, which means that windows API's will default all character strings to the wide version (wchar_t vs char). Try using the wide output version of cout (wcout):
wcout<<File_Data.cFileName;