Related
Context:
I need to scan for, gather information and copy some media files from specific directories.
I have been having quite some trouble with some files not being detected, etc
Problem:
Warning to reader: As seen on the screenshot and noted in a comment,
the title and premise of this question are possible moot, as the error
was more likely to be dec 32 (== 0x20) == ERROR_SHARING_VIOLATION,
which has an "easy" explantion in the answer to this question.
In the code below, I use a c-style cast to convert my QString into a LPCWSTR for the CopyFileExW which I found in this SO post. I have tried many different conversions, but non of them seems to work correctly - which for now is besides the point.
The problem this 'conversion' technique gives is the error ERROR_NOT_SUPPORTED
ERROR_NOT_SUPPORTED
50 (0x32)
The request is not supported.
Frankly, this makes absolutely no sense to me in this context. I am copying from NTFS -> NTFS (same hard drive for testing), with destination file length < 200 characters (see image, 192 to be exact).
The core code: (see bottom for full details)
// QString src (src file location), dst (destination file location)
LPCWSTR localC_src = (LPCWSTR) src.utf16();
LPCWSTR localC_dst = (LPCWSTR) dst.utf16();
LPCWSTR dirC = (LPCWSTR) dir.utf16();
auto rc = CopyFileExW(localC_src, localC_dst, &BackupManager::copyProgress, this, &bStopBackup, 0);
if (rc == 0) {
DWORD lastError = GetLastError(); // Error = 0x32
bool dirExist = DirExists(dirC); // true
bool fileExists = FileExists(localC_src); // true
printWarning(TAG, QString("File Copy Error: %1").arg(getLastErrorMsg()));
#ifdef QT_DEBUG
if (FileExists(localC_src)) {
qDebug() << "#FailedCopy: Windows file exists but copy failed" << src; // this gets hit using the implemented c-style cast
}
else {
if (QFile::exists(src)) {
qDebug() << "#FailedCopy: Windows is really being full of shit! " << src; // this always gets triggered when using QString::toStdWString.c_str()
}
else {
qDebug() << "#FailedCopy: Windows file copy failed outright" << src;
}
}
// ...
} else {
// success
}
What does this error mean in the FileCopyExW context?
(also, if anyone has the source for windows.h implementation to allow me to trace the error further, please post it as a comment)
Image of debugger, etc
Full Code Implemenation:
static QString toString(HRESULT hr)
{
_com_error err{hr};
const TCHAR* lastError = err.ErrorMessage();
return QStringLiteral("Error 0x%1: %2").arg((quint32)hr, 8, 16, QLatin1Char('0'))
.arg(lastError);
}
static QString getLastErrorMsg()
{
DWORD lastError = GetLastError();
QString s = toString(HRESULT_FROM_WIN32(lastError));
return s;
}
BOOL FileExists(LPCWSTR szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
// not used
static const wchar_t* toLPCWSTR(QString s)
{
std::wstring dstWString = s.toStdWString();
const wchar_t* localC_src = dstWString.c_str();
return localC_src;
}
static bool DirExists(LPCWSTR szPath)
{
DWORD ftyp = GetFileAttributes(szPath);
if (ftyp == INVALID_FILE_ATTRIBUTES)
return false; //something is wrong with your path!
if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
return true; // this is a directory!
return false; // this is not a directory!
}
BackupResult BackupManager::copyFile(QString m_src, QString m_dst)
{
QFileInfo fi(m_src);
QString dir = fi.dir().path();
// const wchar_t* dirC = toLPCWSTR(dir);
QString src = QString(m_src).replace("/", "\\");
QString dst = QString(m_src).replace("/", "\\");
// const wchar_t* localC_src = toLPCWSTR(src);
// const wchar_t* localC_dst = toLPCWSTR(dst);
LPCWSTR localC_src = (LPCWSTR) src.utf16();
LPCWSTR localC_dst = (LPCWSTR) dst.utf16();
LPCWSTR dirC = (LPCWSTR) dir.utf16();
auto rc = CopyFileExW(localC_src, localC_dst, &BackupManager::copyProgress, this, &bStopBackup, 0);
if (rc == 0) {
DWORD lastError = GetLastError(); // Error = 0x32
bool dirExist = DirExists(dirC); // true
bool fileExists = FileExists(localC_src); // true
printWarning(TAG, QString("File Copy Error: %1").arg(getLastErrorMsg()));
#ifdef QT_DEBUG
if (FileExists(localC_src)) {
qDebug() << "#FailedCopy: Windows file exists but copy failed" << src; // this gets hit using the implemented c-style cast
}
else {
if (QFile::exists(src)) {
qDebug() << "#FailedCopy: Windows is really being full of shit! " << src; // this always gets triggered when using QString::toStdWString.c_str()
}
else {
qDebug() << "#FailedCopy: Windows file copy failed outright" << src;
}
}
#endif
// copy failed
return BackupResult::IOError;
}
// copy success
return BackupResult::Success;
}
I suggest you check whether the copied file handle is opened in another process.
I created a simple sample, the code is as follows:
#include <iostream>
#include <Windows.h>
using namespace std;
int main(int argc, const char* argv[])
{
CopyFileEx(L"D:\\test\\test.txt", L"D:\\test\\test2.txt", NULL, NULL, 0, 0);
int e = GetLastError();
cout << "error code is :" << e << endl;
return 0;
}
This sample of course successfully copied the file.But if I add the code to open the handle of this file, it will return error code 32.
#include <iostream>
#include <Windows.h>
using namespace std;
int main(int argc, const char* argv[])
{
CreateFileW(L"D:\\test\\test.txt", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
CopyFileEx(L"D:\\test\\test.txt", L"D:\\test\\test2.txt", NULL, NULL, 0, 0);
int e = GetLastError();
cout << "error code is :" << e << endl;
return 0;
}
Outout:
So I think you did not close it properly after opening the handle in other locations. If you need to copy files while the handle is open, you can modify the dwShareMode parameter to FILE_SHARE_READ. In this way, the file copy operation can be performed when the handle is opened.
Here is the sample:
#include <iostream>
#include <Windows.h>
using namespace std;
int main(int argc, const char* argv[])
{
CreateFileW(L"D:\\test\\test.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
CopyFileEx(L"D:\\test\\test.txt", L"D:\\test\\test2.txt", NULL, NULL, 0, 0);
int e = GetLastError();
cout << "error code is :" << e << endl;
return 0;
}
Output:
More reference:CreateFileW and CopyFileExA
I'm dumping the screen of a client window and writing it to the disk using C++ and the Windows API as follows:
const auto window_handle = FindWindow(nullptr, ...);
const auto output_file_path = L"output.png";
// Get the window screenshot
std::cout << "Performing screenshot... ";
HBITMAP bitmap;
const auto screen_shot_successfully_performed = perform_screen_shot(window_handle, bitmap);
if (screen_shot_successfully_performed)
{
std::cout << "OK!" << std::endl;
// Save it
std::cout << "Saving image... ";
const auto saving_image_succeeded = save_image(bitmap, output_file_path);
if (saving_image_succeeded)
{
std::cout << "OK!" << std::endl;
}
}
ImageEncoding.h:
#pragma once
#include <windows.h>
#include <gdiplus.h>
#include <gdiplustypes.h>
#include <iostream>
#include "ErrorHandling.h"
#include "Conversions.h"
using namespace Gdiplus;
#pragma comment (lib, "Gdiplus.lib")
inline int get_encoder(const WCHAR* format, CLSID* p_clsid)
{
UINT image_encoders_count = 0;
UINT image_encoder_array_size = 0;
GetImageEncodersSize(&image_encoders_count, &image_encoder_array_size);
if (image_encoder_array_size == 0)
{
return -1; // Failure
}
const auto p_image_codec_info = static_cast<ImageCodecInfo*>(malloc(image_encoder_array_size));
if (p_image_codec_info == nullptr)
{
return -1; // Failure
}
GetImageEncoders(image_encoders_count, image_encoder_array_size, p_image_codec_info);
for (UINT image_encoder_index = 0; image_encoder_index < image_encoders_count; image_encoder_index++)
{
const auto image_codec_info = p_image_codec_info[image_encoder_index];
const auto mime_type = image_codec_info.MimeType;
const auto comparison_result = wcscmp(mime_type, format);
if (comparison_result == 0)
{
*p_clsid = image_codec_info.Clsid;
free(p_image_codec_info);
return image_encoder_index; // Success
}
}
free(p_image_codec_info);
return -1; // Failure
}
inline WCHAR* get_image_format_from_filename(const WCHAR* filename)
{
std::wstring wide_string_filename(filename);
const std::string filename_string(wide_string_filename.begin(),
wide_string_filename.end());
const auto file_extension = get_file_extension(filename_string);
std::stringstream image_format_buffer;
image_format_buffer << "image/" << file_extension;
const auto encoder_format = image_format_buffer.str();
return to_wide_char(encoder_format.c_str());
}
inline bool save_image(const HBITMAP bitmap, const WCHAR* filename)
{
GdiplusStartupInput gdiplus_startup_input;
ULONG_PTR gdiplus_token;
const auto startup_status = GdiplusStartup(&gdiplus_token, &gdiplus_startup_input, nullptr);
if (startup_status != Gdiplus::Ok)
{
std::cout << "[ERROR] GdiplusStartup() failed: " << startup_status << std::endl;
return false;
}
auto image = new Bitmap(bitmap, nullptr);
CLSID my_cls_id;
const auto format = get_image_format_from_filename(filename);
const auto encoder_return_value = get_encoder(format, &my_cls_id);
if (encoder_return_value == -1)
{
std::cout << "[ERROR] Encoder not available: ";
std::wcout << format << std::endl;
delete image;
return false;
}
const auto image_saving_status = image->Save(filename, &my_cls_id, nullptr);
if (image_saving_status != Gdiplus::Ok)
{
std::cout << "[ERROR] Saving image failed: " << startup_status << std::endl;
delete image;
return false;
}
delete image;
GdiplusShutdown(gdiplus_token);
return true;
}
inline bool perform_screen_shot(const HWND window_handle, HBITMAP& bitmap)
{
RECT rectangle;
const auto successful = GetClientRect(window_handle, &rectangle);
if (!successful)
{
const auto last_error_message = get_last_error_as_string();
std::cout << "[ERROR] Cannot get client rectangle: " << last_error_message << std::endl;
exit(EXIT_FAILURE);
}
if (IsRectEmpty(&rectangle))
{
std::cout << "[ERROR] The client rectangle is empty: Maybe the window is minimized?" << std::endl;
return false;
}
const auto hdc_screen = GetDC(nullptr);
const auto hdc = CreateCompatibleDC(hdc_screen);
bitmap = CreateCompatibleBitmap(hdc_screen,
rectangle.right - rectangle.left,
rectangle.bottom - rectangle.top);
SelectObject(hdc, bitmap);
const auto window_successfully_printed = PrintWindow(window_handle, hdc, PW_CLIENTONLY);
if (!window_successfully_printed)
{
const auto last_error_message = get_last_error_as_string();
std::cout << "[ERROR] Window not printed: " << last_error_message << std::endl;
exit(EXIT_FAILURE);
}
return true;
}
On my machine (Windows 10 Pro 64-bit) this code always works perfectly. As you can see, the return values are validated so errors should be caught. However, another user on Windows 10 64-bit always gets a black screen image despite all the functions succeeding. Is there anything I'm not addressing correctly? How can this bug be fixed? I've tried using PNG and BMP encoders but same outcome (most likely because the HBITMAP was already black at that point).
As commented by Remy Lebeau, PrintWindow() does not seem to be reliable since it directly captures the client part of a window, even if it isn't visible on the screen (e.g. it's behind another window). One thing which seems to work much better is to perform a conventional screenshot and restricting the area to the client area of the target window. This has the disadvantage that the window must be visible to be captured. The code for this is e.g. the following:
// Get the horizontal and vertical screen sizes in pixel
inline POINT get_window_resolution(const HWND window_handle)
{
RECT rectangle;
GetClientRect(window_handle, &rectangle);
const POINT coordinates{rectangle.right, rectangle.bottom};
return coordinates;
}
#include <iostream>
#include <ole2.h>
#include <olectl.h>
inline bool save_bitmap(const LPCSTR file_path,
const HBITMAP bitmap, const HPALETTE palette)
{
PICTDESC pict_description;
pict_description.cbSizeofstruct = sizeof(PICTDESC);
pict_description.picType = PICTYPE_BITMAP;
pict_description.bmp.hbitmap = bitmap;
pict_description.bmp.hpal = palette;
LPPICTURE picture;
auto initial_result = OleCreatePictureIndirect(&pict_description, IID_IPicture, false,
reinterpret_cast<void**>(&picture));
if (!SUCCEEDED(initial_result))
{
return false;
}
LPSTREAM stream;
initial_result = CreateStreamOnHGlobal(nullptr, true, &stream);
if (!SUCCEEDED(initial_result))
{
picture->Release();
return false;
}
LONG bytes_streamed;
initial_result = picture->SaveAsFile(stream, true, &bytes_streamed);
const auto file = CreateFile(file_path, GENERIC_WRITE, FILE_SHARE_READ, nullptr,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (!SUCCEEDED(initial_result) || !file)
{
stream->Release();
picture->Release();
return false;
}
HGLOBAL mem = nullptr;
GetHGlobalFromStream(stream, &mem);
const auto data = GlobalLock(mem);
DWORD bytes_written;
auto result = WriteFile(file, data, bytes_streamed, &bytes_written, nullptr);
result &= bytes_written == static_cast<DWORD>(bytes_streamed);
GlobalUnlock(mem);
CloseHandle(file);
stream->Release();
picture->Release();
return result;
}
inline POINT get_client_window_position(const HWND window_handle)
{
RECT rectangle;
GetClientRect(window_handle, static_cast<LPRECT>(&rectangle));
MapWindowPoints(window_handle, nullptr, reinterpret_cast<LPPOINT>(& rectangle), 2);
const POINT coordinates = {rectangle.left, rectangle.top};
return coordinates;
}
// https://stackoverflow.com/a/9525788/3764804
inline bool capture_screen_client_window(const HWND window_handle, const LPCSTR file_path)
{
SetActiveWindow(window_handle);
const auto hdc_source = GetDC(nullptr);
const auto hdc_memory = CreateCompatibleDC(hdc_source);
const auto window_resolution = get_window_resolution(window_handle);
const auto width = window_resolution.x;
const auto height = window_resolution.y;
const auto client_window_position = get_client_window_position(window_handle);
auto h_bitmap = CreateCompatibleBitmap(hdc_source, width, height);
const auto h_bitmap_old = static_cast<HBITMAP>(SelectObject(hdc_memory, h_bitmap));
BitBlt(hdc_memory, 0, 0, width, height, hdc_source, client_window_position.x, client_window_position.y, SRCCOPY);
h_bitmap = static_cast<HBITMAP>(SelectObject(hdc_memory, h_bitmap_old));
DeleteDC(hdc_source);
DeleteDC(hdc_memory);
const HPALETTE h_palette = nullptr;
if (save_bitmap(file_path, h_bitmap, h_palette))
{
return true;
}
return false;
}
It is based on this answer.
I want to use espeak in my program. I'd like to know when espeak stops speaking. Are there any flags or functions to check?
Let's consider this is my program:
Line 1
espeak
Line 2
When I execute this code, espeak starts to say "hello, this is espeak" but before it ends, Line 2 of code is executed, and I don't like this. I am looking for a way to pause the program until espeak ends the speaking!
EDIT:
This is my complete code, I use pocketsphinx to recognize what the user say, then save it inside char* hyp and pass it through espeak by speech function.
static ps_decoder_t *ps;
static cmd_ln_t *config;
static FILE *rawfd;
espeak_POSITION_TYPE position_type;
espeak_AUDIO_OUTPUT output;
char *path=NULL;
int Buflength = 1000, Options=0;
void* user_data;
char Voice[] = {"English"};
char text2[30] = {"this is a english test"};
unsigned int Size,position=0, end_position=0, flags=espeakCHARS_AUTO, *unique_identifier;
t_espeak_callback *SynthCallback;
espeak_PARAMETER Parm;
//char* text;
static void initFuncs()
{
output = AUDIO_OUTPUT_PLAYBACK;
espeak_Initialize(output, Buflength, path, Options );
espeak_SetVoiceByName(Voice);
const char *langNativeString = "en";
espeak_VOICE voice;
memset(&voice, 0, sizeof(espeak_VOICE));
voice.languages = langNativeString;
voice.name = "US";
voice.variant = 2;
voice.gender = 1;
espeak_SetVoiceByProperties(&voice);
}
static void sleep_msec(int32 ms)
{
struct timeval tmo;
tmo.tv_sec = 0;
tmo.tv_usec = ms * 1000;
select(0, NULL, NULL, NULL, &tmo);
}
static void speech(char* hyp)
{
Size = strlen(hyp)+1;
espeak_Synth( hyp, Size, position, position_type, end_position, flags,unique_identifier, user_data );
espeak_Synchronize( );
}
static void recognize_from_microphone()
{
ad_rec_t *ad;
int16 adbuf[2048];
uint8 utt_started, in_speech;
int32 k;
char *hyp;
if ((ad = ad_open_dev(cmd_ln_str_r(config, "-adcdev"),(int) cmd_ln_float32_r(config,"-samprate"))) == NULL)
E_FATAL("Failed to open audio device\n");
if (ad_start_rec(ad) < 0)
E_FATAL("Failed to start recording\n");
if (ps_start_utt(ps) < 0)
E_FATAL("Failed to start utterance\n");
utt_started = FALSE;
E_INFO("Ready....\n");
for (;;) {
ad_start_rec(ad);
if ((k = ad_read(ad, adbuf, 2048)) < 0)
E_FATAL("Failed to read audio\n");
ps_process_raw(ps, adbuf, k, FALSE, FALSE);
in_speech = ps_get_in_speech(ps);
if (in_speech && !utt_started) {
utt_started = TRUE;
E_INFO("Listening...\n");
}
if (!in_speech && utt_started) {
ps_end_utt(ps);
hyp = (char*)ps_get_hyp(ps, NULL );
if (hyp != NULL) {
ad_stop_rec(ad);
speech(hyp);
printf("%s\n", hyp);
fflush(stdout);
}
if (ps_start_utt(ps) < 0)
E_FATAL("Failed to start utterance\n");
utt_started = FALSE;
E_INFO("Ready....\n");
}
}//for loop
ad_close(ad);
}
int main(int argc, char *argv[])
{
initFuncs();
config = cmd_ln_init(NULL, ps_args(), TRUE,
"-hmm", MODELDIR "/en-us/en-us",
"-lm", MODELDIR "/en-us/en-us.lm.bin",
"-dict", MODELDIR "/en-us/cmudict-en-us.dict",
NULL);
ps = ps_init(config);
recognize_from_microphone();
ps_free(ps);
cmd_ln_free_r(config);
return 0;
}
I adapted the espeak part of your code. In this code espeak is finished before Line 2 begins. Also the callback functionality is implemented. You are setting a voice by name and a voice by property. Maybe this is a problem. You are working with c-style strings and not with std::string. Maybe you are calculating the wrong string length. I don't know where the problem in your code is but the following code has fixed it:
#include <string>
#include <iostream>
#include <espeak/speak_lib.h>
espeak_POSITION_TYPE position_type(POS_CHARACTER);
espeak_AUDIO_OUTPUT output(AUDIO_OUTPUT_PLAYBACK);
void* user_data;
std::string voice("English");
std::string text("this is a english test");
unsigned int Size(0);
unsigned int position(0);
unsigned int end_position(0);
unsigned int flags(espeakCHARS_AUTO);
unsigned int* unique_identifier;
static void initFuncs() {
espeak_Initialize(output, 0, 0, 0);
espeak_SetVoiceByName(voice.c_str());
}
int SynthCallback(short *wav, int numsamples, espeak_EVENT *events) {
std::cout << "Callback: ";
for (unsigned int i(0); events[i].type != espeakEVENT_LIST_TERMINATED; i++) {
if (i != 0) {
std::cout << ", ";
}
switch (events[i].type) {
case espeakEVENT_LIST_TERMINATED:
std::cout << "espeakEVENT_LIST_TERMINATED";
break;
case espeakEVENT_WORD:
std::cout << "espeakEVENT_WORD";
break;
case espeakEVENT_SENTENCE:
std::cout << "espeakEVENT_SENTENCE";
break;
case espeakEVENT_MARK:
std::cout << "espeakEVENT_MARK";
break;
case espeakEVENT_PLAY:
std::cout << "espeakEVENT_PLAY";
break;
case espeakEVENT_END:
std::cout << "espeakEVENT_END";
break;
case espeakEVENT_MSG_TERMINATED:
std::cout << "espeakEVENT_MSG_TERMINATED";
break;
case espeakEVENT_PHONEME:
std::cout << "espeakEVENT_PHONEME";
break;
case espeakEVENT_SAMPLERATE:
std::cout << "espeakEVENT_SAMPLERATE";
break;
default:
break;
}
}
std::cout << std::endl;
return 0;
}
static void speech(std::string hyp) {
Size = hyp.length();
espeak_SetSynthCallback(SynthCallback);
espeak_Synth(hyp.c_str(), Size, position, position_type, end_position, flags,unique_identifier, user_data );
espeak_Synchronize( );
}
int main() {
initFuncs();
std::cout << "Start" << std::endl;
speech(text.c_str());
std::cout << "End" << std::endl;
return 0;
}
The out put is
Start
Callback: espeakEVENT_SENTENCE
Callback: espeakEVENT_WORD
Callback: espeakEVENT_WORD
Callback: espeakEVENT_WORD
Callback: espeakEVENT_WORD
Callback: espeakEVENT_WORD
Callback: espeakEVENT_END
Callback: espeakEVENT_MSG_TERMINATED
End
The timing of the console outout fits to the audio output. When you are working with C++, then you should use its tools and features like strings, cout instead of printf and smart pointers to avoid problems like this.
Is there someone that can explain me how i can get files from directories inside a zipfile.
I use c++ and miniz(code.google.com/p/miniz/). thank you in advance.
here my code i have that i use right now:
size_t uncomp_size;
mz_bool status;
mz_zip_archive zip_archive;
memset(&zip_archive, 0, sizeof(zip_archive));
status = mz_zip_reader_init_file(&zip_archive, "data.zip", 0);
if (!status){
puts("failed to open zip file\n");
return 0;
}
try{
void* p = NULL;
std::string file_to_extract = "data//test.txt";
int file_index = mz_zip_reader_locate_file(&zip_archive, file_to_extract.c_str(), NULL, MZ_ZIP_FLAG_IGNORE_PATH);
if (file_index < 0)
{
mz_bool is_dir = mz_zip_reader_is_file_a_directory(&zip_archive,file_index);
if(is_dir){
throw std::exception("file_index = folder");
}else{
throw std::exception("cannot find file in zip(0)");
}
}
p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, &uncomp_size, NULL);
if(!p){
throw std::exception("cannot find file in zip(1)");
}
std::fstream fp1("test.txt",ios::binary|ios::out);
fp1.write(reinterpret_cast<char*>(p),uncomp_size);
fp1.close();
delete p;
}catch(std::exception ex){
cout << ex.what() << endl;
}
mz_zip_reader_end(&zip_archive);
This code is working for me using miniz from here.
string str_zip; // The zip archive in string form.
string str_unzip; // The uncompressed contents of the first file in the zip archive.
// Read in or assign zip contents to the string.
// In my case I receive the zip file via a web service.
// The processing all takes place in memory.
// But you can easily read a file's contents into the zipfile string, as well.
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint;
mz_zip_archive zip_archive;
mz_bool status;
// Now try to open the archive.
memset(&zip_archive, 0, sizeof(zip_archive));
// You can provide the zip data in memory as I did...
status = mz_zip_reader_init_mem(&zip_archive, str_zip.c_str(), str_zip.size(), 0);
// Or you can just give a filename...
// status = mz_zip_reader_init_file(&zip_archive, "myfile.zip", 0);
if (!status)
{
cout << "zip file appears invalid..." << endl;
return;
}
// Get the first file in the archive.
if (mz_zip_reader_get_num_files(&zip_archive) != 1)
{
cout << "zip file does not contain our 1 file..." << endl;
return;
}
mz_zip_archive_file_stat file_stat;
if (!mz_zip_reader_file_stat(&zip_archive, 0, &file_stat))
{
cout << "zip file read error..." << endl;
mz_zip_reader_end(&zip_archive);
return;
}
// Unzip the file to heap.
size_t uncompressed_size = file_stat.m_uncomp_size;
void* p = mz_zip_reader_extract_file_to_heap(&zip_archive, file_stat.m_filename, &uncompressed_size, 0);
if (!p)
{
cout << "mz_zip_reader_extract_file_to_heap() failed..." << endl;
mz_zip_reader_end(&zip_archive);
return;
}
str_unzip.assign((const char*)p,uncompressed_size);
// Close the archive, freeing any resources it was using
mz_free(p);
mz_zip_reader_end(&zip_archive);
I came up with a solution for this.
Lets we have;
In your C directory:
+-- ZipFile /
+-- folder1 /
+-- file1
+-- folder2 /
+--file2.1
+--file2.2
+--file2.3
bool decompress_folders_inside_zip()
{
const std::string archive_name = "ZipFile.zip";
const std::string decompress_path = "C:\\";
mz_zip_archive archive {};
boost::filesystem::path dec_path { decompress_path + archive_name };
if (!mz_zip_reader_init_file(&archive, dec_path.string().c_str(), 0))
{
return false;
}
const int file_cnt = (int)mz_zip_reader_get_num_files(&archive);
if (0 == file_cnt)
{
return false;
}
mz_zip_archive_file_stat file_stat;
if (!mz_zip_reader_file_stat(&archive, 0, &file_stat))
{
mz_zip_reader_end(&archive);
return false;
}
for (int i = 0; i < file_cnt; ++i)
{
mz_zip_reader_file_stat(&archive, i, &file_stat);
if (mz_zip_reader_is_file_a_directory(&archive, i))
{
boost::filesystem::path dir(decompress_path + file_stat.m_filename);
boost::filesystem::create_directories(dir.parent_path());
continue;
}
boost::filesystem::path file_out(decompress_path + file_stat.m_filename);
boost::filesystem::path out_file(file_out.parent_path().generic_string() + "/" + file_out.filename().string());
if (!mz_zip_reader_extract_to_file(&archive, i, out_file.string().c_str(), 0))
{
mz_zip_reader_end(&archive);
return false;
}
}
if (!mz_zip_reader_end(&archive))
{
return false;
}
std::cout << "Completed" << std::endl;
return true;
}
hi i want to write a little program to change the wallpaper in windows 7
i wanted to use the following code:
#include "windows.h"
#include "wininet.h"
#include "shlobj.h"
#include "wchar.h"
#include <iostream>
void SetWallpaper(LPCWSTR file){
CoInitializeEx(0,COINIT_APARTMENTTHREADED);
IActiveDesktop* desktop;
HRESULT status = CoCreateInstance(CLSID_ActiveDesktop,NULL,CLSCTX_INPROC_SERVER,IID_IActiveDesktop,(void**)&desktop);
WALLPAPEROPT wOption;
ZeroMemory(&wOption, sizeof(WALLPAPEROPT));
wOption.dwSize=sizeof(WALLPAPEROPT);
wOption.dwStyle = WPSTYLE_CENTER;
status = desktop->SetWallpaper(file,0);
wcout << status << endl;
status = desktop->SetWallpaperOptions(&wOption,0);
wcout << status << endl;
status = desktop->ApplyChanges(AD_APPLY_ALL);
wcout << status << endl;
desktop->Release();
CoUninitialize();
}
int wmain(int argc, wchar* argv[]){
if(argc<=1){
wcout << "use: " << argv[0] <<" path_to_pic.bmp" <<endl;
}else{
wchar_t* file = argv[1];
SetWallpaper(file);
}
getchar();
return 0;
}
but this code does not change the wallpaper, it only gives me the hresult error-code 80070002 after calling ApplyChanges.
what am i doing wrong please help
Please change your main entry function from
int main(int argc, char* argv[])
to
int wmain(int argc, wchar_t* argv[] )
No casting is necessary like wchar_t* file = (wchar_t*)argv[1]; and it will just work as your wmain arguments are already in wchar_t*
I was able to use your code and my modification and change my computer wall paper
Here's a promising-looking piece of code
http://answers.google.com/answers/threadview/id/512662.html
though I haven't tested it myself:
#include <windows.h>
#include <stdio.h>
const SPI_GETDESKWALLPAPER=115;
void printusage(char *program)
{
fprintf(stderr, "Usage: %s background-file.bmp\n", program);
fprintf(stderr, " Changes desktop background to background-file\n");
return;
}
int main(int argc, char *argp[])
{
DWORD dResult;
BOOL result;
char oldWallPaper[255];
if (argc != 2) {
printusage(argp[0]);
return 1;
}
result = SystemParametersInfo(
SPI_GETDESKWALLPAPER,
sizeof(oldWallPaper)-1,
oldWallPaper,
0);
fprintf(stderr, "Current desktop background is %s\n", oldWallPaper);
result = SystemParametersInfo(
SPI_SETDESKWALLPAPER,
0,
argp[1],
0);
if (!result) {
dResult = GetLastError();
fprintf(stderr, "Attempt to set new desktop background failed; code
%d\n", dResult);
fprintf(stderr, "Will restore prior setting (%s)\n", oldWallPaper);
result = SystemParametersInfo(
SPI_SETDESKWALLPAPER,
0,
oldWallPaper,
0);
return 2;
}
fprintf(stderr, "Desktop background changed to %s\n", argp[1]);
return 0;
}
Code to change your wallpaper with two (or multiple , add more conditions) images ..
#include <windows.h>
int main()
{
int i;
for(i=0;;i++)
{
Sleep(1600);
if(i%2==0)
{
const wchar_t *filenm = L"C:\\Pictures\\image1.jpg"; //ADDRESS of first image
bool isWallSet=SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0,(void*)filenm,SPIF_UPDATEINIFILE);
}
else
{
const wchar_t *filenm = L"C:\\Pictures\\image2.jpg"; //ADDRESS of second image
bool isWallSet=SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0,(void*)filenm,SPIF_UPDATEINIFILE);
}
}
return 0;
}