how to change active desktop wallpaper in c++ - c++

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;
}

Related

FileCopyExW reports last error as ERROR_NOT_SUPPORTED - what does this mean in terms of FileCopyExW

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

C++ odbc Query not actually inserting record

I'm currently attempting to build a simple C++ program to insert a record into a MS Sql Server database. The code executes and return codes indicate that things technically worked, yet no record is actually getting inserted to the database. I'm at a lose as to what might be causing the issue. Driver maybe?
Originally I intended to use prepared statements and avoid any string copying, but I couldn't seem to get those to work properly. So, to test if anything would happen at all, I build a query as below. Not the best approach and not my intended approach but I can't even seem to get a record inserted to the db.
Return codes do not indicate problems with the connection (please note, I've changed the actual connection information) or even the execution of the query, which leans me towards perhaps needing a commit? Also why I might be inclined to think it is the driver. Thoughts?
Here is the code:
stdafx.h
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
#include <Windows.h>
#include <winnt.h>
#include <sqlext.h>
#include <rpc.h>
#include <iostream>
#pragma comment(lib, "rpcrt4.lib")
And testCamel2Db.cpp
// testCamel2Db.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
INT connectDb(VOID);
int _tmain(int argc, _TCHAR* argv[])
{
connectDb();
return 0;
}
INT connectDb (VOID)
{
RETCODE rc; //ODBC return code
HENV henv; //environment handle
HSTMT hstmt;//statement handle
HDBC hdbc; //connection handle
SQLAllocEnv(&henv);
SQLAllocConnect(henv, &hdbc);
rc = SQLDriverConnect(
hdbc,
NULL,
(unsigned char*)"DRIVER={SQL Server};SERVER=server.name.edu,3433;DATABASE=camel2;UID=username;PWD=password;",
SQL_NTS,
NULL,
0,
NULL,
SQL_DRIVER_COMPLETE);
if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
{
//error handling here
std::cout << "no connection created.";
return 1;
}
//create a uuid
UUID uuid;
UuidCreate(&uuid);
unsigned char* uuidStr;
UuidToStringA(&uuid,&uuidStr);
INT quotedUuidSize = strlen((char*)uuidStr) + 2;
char* quotedUuidStr = new char[quotedUuidSize +1];
memset(quotedUuidStr, 0, sizeof(char) * quotedUuidSize + 1);
strcat(quotedUuidStr, "'");
strcat(quotedUuidStr, (char*)uuidStr);
strcat(quotedUuidStr, "'");
//admin_user variable
LPSTR adminUser;
adminUser = "'Active Directory'";
//build a query
LPSTR sql = "INSERT cw_ResetCheck (ResetUID, AdminUser ) values (";
INT queryStrSize = strlen(sql) + strlen((char*)quotedUuidStr) + strlen(adminUser) + 2;
char* queryStr = new char[queryStrSize + 1];
memset(queryStr, 0, sizeof(char) * (queryStrSize + 1));
strcat(queryStr,sql);
strcat(queryStr,(char*)quotedUuidStr);
strcat(queryStr,",");
strcat(queryStr,adminUser);
strcat(queryStr,")");
std::cout << queryStr << "\n";
rc = SQLAllocStmt(hdbc,&hstmt);
std::cout << uuidStr;
rc = SQLExecDirect(hstmt, (SQLCHAR*)queryStr, SQL_NTS);
if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
{
std::cout << "query failed";
return 1;
}
else
{
std::cout << "uid created: ";
std::cout << uuidStr;
}
//close database
SQLFreeStmt(hstmt,SQL_DROP);
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
return 0;
}

Program crashes after loading image (GDIplus)

I wanted to write a program which loads an image given by command line and afterwards does something with it. My problem now is: Whenever I execute the program it prints me the palette size of the image (which gives me a wrong output (12) for every picture in jpg format I enter), and afterwards it crashes, but I can not figure out my mistake.
What am I doing wrong?
inline bool exists(const std::string& name) {
if (FILE *file = fopen(name.c_str(), "r")) {
fclose(file);
return true;
}
else {
return false;
}
}
int main(int argc, char* argv[])
{
if (argc != 3)
{
std::cout << "Too few/too much arguments. Usage: ShrinkImage <Input-File> <Number of target colours>\n";
return 0;
}
int num_colors;
char * filepath = argv[1];
if (!exists(filepath))
{
std::cout << "File does not exist.\n";
return 0;
}
num_colors = std::stoi(argv[2], nullptr);
ULONG_PTR(m_gdiplusToken);
Gdiplus::GdiplusStartupInput gdiplusstartupinput;
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusstartupinput, NULL);
const size_t cSize = strlen(filepath) + 1;
size_t Size = cSize - 1;
wchar_t *wc = new wchar_t[cSize];
swprintf(wc, cSize, L"%hs", filepath);
Gdiplus::Image image(wc);
std::cout << image.GetPaletteSize() << '\n';
std::cout << "Printed PaletteSize\n";
delete wc;
Gdiplus::GdiplusShutdown(m_gdiplusToken);
std::cout << "After Shutdown\n";
return 0;
}
Solution is:
Writing instead of
Gdiplus::Image image(wc);
this:
Gdiplus::Image * image = Gdiplus::Image::FromFile(wc);
delete image;
image = 0;
This solves my problem.

WaitForSingleObject on a semaphore does not wait, returns immediately

I'm trying to make a simple client-server program using windows file mapping and that uses semaphores. The clients send to the server 2 numbers, the server computes nr1+nr2 and nr1 * nr2. I tried something but it doesn't even work for 1 client and I want it to work for more clients. Here's the code:
the server:
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
typedef struct {
int nr1;
int nr2;
} Mesaj;
int main(int argc, char** argv) {
Mesaj* mesaj;
HANDLE createSemaphore = CreateSemaphore(NULL, 1, 1, "Semafor");
if (createSemaphore == NULL || createSemaphore == INVALID_HANDLE_VALUE) {
wcout << "Failed to create a semaphore\n";
} else {
wcout << "Created the semaphore\n";
}
HANDLE hMemory = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
PAGE_READWRITE, 0, sizeof(Mesaj), "SharedMemory");
WaitForSingleObject(createSemaphore, INFINITE);
mesaj = (Mesaj*) MapViewOfFile(hMemory, FILE_MAP_READ, 0, 0, sizeof(Mesaj));
printf("The numbers received are: %d, %d\n", mesaj->nr1, mesaj->nr2);
int produs = mesaj->nr1 * mesaj->nr2;
int suma = mesaj->nr1 + mesaj->nr2;
printf("\nSuma numerelor este: %d iar produsul lor este: %d", suma, produs);
ReleaseSemaphore(createSemaphore, 1, NULL);
Sleep(INFINITE);
return 0;
}
the client:
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
typedef struct {
int nr1;
int nr2;
} Mesaj;
int main(int argc, char** argv) {
Mesaj* mesaj, *mesaj2;
mesaj2 = (Mesaj*) malloc(sizeof(Mesaj));
HANDLE hMemory = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE,
"SharedMemory");
if (hMemory == NULL) {
wcout << "Error at OpenFileMapping\n";
}
HANDLE openSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS,TRUE,"Semafor");
if(openSemaphore != NULL || openSemaphore != INVALID_HANDLE_VALUE){
wcout<<"the semaphore is opened\n";
}
mesaj2 = (Mesaj*) MapViewOfFile(hMemory, FILE_MAP_WRITE, 0, 0,
sizeof(Mesaj));
int nr1 = 0, nr2 = 0;
printf("Give a number: ");
scanf("%d", &nr1);
printf("Give another number: ");
scanf("%d", &nr2);
mesaj2->nr1 = nr1;
mesaj2->nr2 = nr2;
if (mesaj2 == NULL) {
wcout << "Error\n"
} else {
wcout << "I sent " << mesaj2->nr1 << " and " << mesaj2->nr2 << endl;
}
system("pause");
return 0;
}
What exactly am I doing wrong? How should I work with semaphores?
When I open the server it doesn't wait for the client.
The documentation for CreateSemaphore says
The state of a semaphore object is signaled when its count is greater than zero, and nonsignaled when its count is equal to zero. The lInitialCount parameter specifies the initial count.
You passed lInitialCount=1 when you created the semaphore. and 1 > 0, so the semaphore is signaled and the WaitForSingleObject returns immediately.
You presumably want to create the semaphore with an initial count of 0, so that it does not become signaled until somebody calls ReleaseSemaphore.

program that reacts to inotify and prints the events

I am working in Ubuntu. I want to monitor a folder and print every event that pops up in the subfolders (print files).
I have the following code but it doesn't work. When executed, there is no println of the events.
In the second code I only see the events from the folder. The events from each subfolder do not pop up.
#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
std::string exec(char* cmd) {
FILE* pipe = popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[256];
std::string result = "";
while(!feof(pipe)) {
if(fgets(buffer, 256, pipe) != NULL)
result += buffer;
}
pclose(pipe);
cout<<"result is: "<<result<<endl;
return result;
}
int main()
{
//while(1)
//{
string s=exec((char*)"inotifywait -rme create /home/folder/");
cout << s << endl;
//}
return 0;
}
This code only prints the events from the folder I'm monitoring. It doesn't print the events from each subfolder. I don't know how to improve it for my needs.
#include <sys/inotify.h>
#include <sys/ioctl.h>
#include <iostream>
void processNewFiles(int fd, int wd);
int main(int argc, char** argv)
{
const char* dirPath = "/home/folder/" ;//argv[1];
int fd = inotify_init();
int wd = inotify_add_watch(fd, dirPath, IN_CREATE);
if (wd)
{
processNewFiles(fd, wd);
inotify_rm_watch(fd, wd);
}
}
void processNewFiles(int fd, int wd)
{
bool done = false;
do
{
int qLen = 0;
ioctl(fd, FIONREAD, &qLen);
char* buf = new char[qLen];
int num = read(fd, buf, qLen);
if (num == qLen)
{
inotify_event* iev = reinterpret_cast<inotify_event*>(buf);
if (iev->wd == wd && iev->mask & IN_CREATE)
{
std::cout << "New file created: " << iev->name << std::endl;
}
}
delete [] buf;
} while (!done);
}
Your second solution does not work because inotify_add_watch is not working recursivly. You would have to add watches for subdirectories manually. As this might be annoying, it is also possible to use the utility inotifywait as you do in your first example.
Your first example is not working because you're reading from the pipe forever. If you kill the inotifywait process (e.g. if you're the only person on the machine and this is the only inotifywait process just using "killall inotifywait") you will get your output because you'll break out of the loop reading from the pipe. If you output something inside the loop, it will work, too.