I have been working on an application to set the desktop background basing of another application I found here: http://www.optimumx.com/downloads.html#SetWallpaper. The idea is to set the background to a wallpaper every 10 minutes, so it launches the SetWallpaper.exe with the command 'SetWallpaper.exe /D:S Wallpaper.jpg' but when I launch my application it creates a console window that doesn't automatically close and when I manually close it, it kills the exe.
#include <windows.h>
int main() {
int i = 1;
int j = 3;
// refresh = time until refresh in minutes
int refresh = 10;
// 1000 milliseconds = 1 second
int second = 1000;
int minute = 60;
int time = second * minute * refresh;
while (i < j) {
system("cmd /c start /b SetWallpaper.exe /D:S Wallpaper.jpg");
Sleep(time);
}
return 0;
}
I tried using 'sleep.exe' that comes with MinGW Msys but that creates a new process each team, eventually hogging all the processes.
Thanks in advance!
The first problem you're having is that you've created your program as a console application with a main method. Instead, create it as a Win32 Project with a WinMain entry point. This will be invoked directly without creating a console window.
EDIT: The second issue is addressed by Ferruccio's answer in that you're invoking another console application from yours which will also result in a console window being created.
You're going about it the hard way. It's fairly simple to change the Windows wallpaper in a program:
#include <windows.h>
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (PVOID) "path/to/wallpaper.jpg", SPIF_UPDATEINIFILE);
In any case, if you insist on launching an external program to do it. Use CreateProcess. It has the ability to launch console mode apps without a visible window, by setting the dwCreationFlags parameter to CREATE_NO_WINDOW.
Set ShowWindow to false and don't forget to FreeConsole at the end.
#include <windows.h>
int main(void)
{
ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);
// put your code here
system("cmd /c start /b SetWallpaper.exe /D:S Wallpaper.jpg");
FreeConsole();
return 0;
}
And as Ferruccio mentioned, You can use SetTimer and SystemParametersInfo to trigger a change periodically.
#define STRICT 1
#include <windows.h>
#include <iostream.h>
VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
LPWSTR wallpaper_file = L"C:\\Wallpapers\\wallpaper.png";
int return_value = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, wallpaper_file, SPIF_UPDATEINIFILE);
cout << "Programmatically change the desktop wallpaper periodically: " << dwTime << '\n';
cout.flush();
}
int main(int argc, char *argv[], char *envp[])
{
int Counter=0;
MSG Msg;
UINT TimerId = SetTimer(NULL, 0, 2000, &TimerProc); //2000 milliseconds = change every 2 seconds
cout << "TimerId: " << TimerId << '\n';
if (!TimerId)
return 16;
while (GetMessage(&Msg, NULL, 0, 0))
{
++Counter;
if (Msg.message == WM_TIMER)
cout << "Counter: " << Counter << "; timer message\n";
else
cout << "Counter: " << Counter << "; message: " << Msg.message << '\n';
DispatchMessage(&Msg);
}
KillTimer(NULL, TimerId);
return 0;
}
Related
Firstly, I'm using VS2008 (doesn't support C++11). I can't upgrade and need to use native libraries only because it needs to be compiled on another persons' compiler which I don't have control over.
I would like to run the code automatically after 5 seconds without having to poll how many seconds have elapsed.
This is my incomplete code
#include <windows.h>
#include <iostream>
void runMeAfterFiveSeconds(){
cout<<"I'm activated!"<<endl;
}
void main(){
while(1){
cout<<"hello there!"<<endl;
Sleep(2000);
}
}
Example output
hello there!
hello there! //after 2 seconds
hello there! //after 4 seconds
I'm activated! //after 5 seconds
hello there! //after 6 seconds
hello there! //after 8 seconds
hello there! //after 10 seconds
I'm activated! //after 10 seconds
...
This example shows how to do it using a very simple scheduling algorithm. No spawning of additional threads is required.
#include <stdio.h>
#include <windows.h>
int main(int argc, char ** argv)
{
DWORD now = timeGetTime();
DWORD nextPrintHelloThereTime = now;
DWORD nextPrintImActivatedTime = now+5000;
while(1)
{
now = timeGetTime();
DWORD nextEventTime = (nextPrintHelloThereTime < nextPrintImActivatedTime) ? nextPrintHelloThereTime : nextPrintImActivatedTime;
DWORD millisecondsToSleep = nextEventTime-now;
Sleep(millisecondsToSleep);
now = timeGetTime();
if (now >= nextPrintHelloThereTime)
{
printf("hello there!\n");
nextPrintHelloThereTime += 2000;
}
if (now >= nextPrintImActivatedTime)
{
printf("I'm activated!\n");
nextPrintImActivatedTime += 5000;
}
}
}
It really depends on what code you want to execute and how you want it to be executed.
The very simple way of doing so would be creating a separate thread and Sleep() in it.
So, since you cannot upgrade from Visual Studio 2008 (which, if I remember correctly, does not support C++11), you have to use either native Windows threads or some library implementation like Boost.Thread.
To look up how to use Windows threads, see MSDN documentation on _beginthreadex() function.
A short tutorial about Boost.Thread can bee seen here.
Quick examples of both, taken directly from the links I provided:
1) Windows threads:
// crt_begthrdex.cpp
// compile with: /MT
#include <windows.h>
#include <stdio.h>
#include <process.h>
unsigned Counter;
unsigned __stdcall SecondThreadFunc( void* pArguments )
{
printf( "In second thread...\n" );
while ( Counter < 1000000 )
Counter++;
_endthreadex( 0 );
return 0;
}
int main()
{
HANDLE hThread;
unsigned threadID;
printf( "Creating second thread...\n" );
// Create the second thread.
hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, &threadID );
// Wait until second thread terminates. If you comment out the line
// below, Counter will not be correct because the thread has not
// terminated, and Counter most likely has not been incremented to
// 1000000 yet.
WaitForSingleObject( hThread, INFINITE );
printf( "Counter should be 1000000; it is-> %d\n", Counter );
// Destroy the thread object.
CloseHandle( hThread );
}
2) Boost.Thread:
struct callable
{
void operator()();
};
boost::thread copies_are_safe()
{
callable x;
return boost::thread(x);
} // x is destroyed, but the newly-created thread has a copy, so this is OK
In the second example, you could as well have used a plain function pointer as boost::thread constructor argument. Moreover, you could use a pointer to function with multiple arguments - a luxury Windows API's threads do not provide.
You're probably just going to need to create a thread like so:
#include <windows.h>
#include <iostream>
#include <thread>
void runMeAfterFiveSeconds(){
while(true){
sleep(5000);
cout<<"I'm activated!"<<endl;
}
}
void main(){
std::thread th(runMeAfterFiveSeconds);
while(1){
cout<<"hello there!"<<endl;
Sleep(2000);
}
}
You're going to have to either make a thread (Coding Orange's answer, probably the better way), or just write it all out.
void runMeAfterFiveSeconds(){
cout << "I'm activated!" <<endl;
}
void main(){
while(1){
cout << "hello there!" << endl;
Sleep(2000);
cout << "hello there!" << endl;
Sleep(3000);
runMeAfterFiveSeconds();
Sleep(1000);
cout << "hello there!" << endl;
Sleep(2000);
cout << "hello there!" << endl;
Sleep(2000);
cout << "hello there!" << endl;
runMeAfterFiveSeconds();
}
}
When, I open some of the software applications I have to wait 2-3 seconds until window will show on desktop. I have to use Sleep(2000); and then call method set always on top. I'm trying to replace Sleep in my code. I would like to get signal from opened window and after this, call a method, which allows opened window be always on top.
Here's my code:
BOOL CALLBACK EnumWindowsProc(HWND windowHandle, LPARAM lParam)
{
DWORD searchedProcessId = (DWORD)lParam;
DWORD windowProcessId = 0;
GetWindowThreadProcessId(windowHandle, &windowProcessId);
cout << "Process id: " << windowProcessId << endl;
if(searchedProcessId == windowProcessId) {
HWND hwnd = windowHandle;
Sleep(2000);
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
cout << "Process ID found!" << endl;
return TRUE;
}
return TRUE;
}
void AlwaysOnTop(int processId)
{
EnumWindows(&EnumWindowsProc, (LPARAM)processId);
}
void AlwaysOnTop(char *name)
{
cout << "String: " << name << endl;
Sleep(2000);
HWND h = FindWindow(NULL, (LPCSTR) name);
SetActiveWindow(h);
SetForegroundWindow(h);
SetWindowPos(h, HWND_TOPMOST, 0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
}
int main()
{
char s[] = {"Application"};
AlwaysOnTop(s);
//AlwaysOnTop(2307);
system("PAUSE");
return 0;
}
Probably the best you can do is to call WaitForInputIdle:
Waits until the specified process has finished processing its initial input and is waiting for user input with no input pending, or until the time-out interval has elapsed.
This is the closest you can get to a general way to wait until a process is showing its UI. It won't always do what you want, but it's the best there is.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I created a system wide hook DLL and in my DLL I am trying to get notified each time a new process is created or destroyed. Whenever a new process is being detected, I want to be able to send a message to the calling program, be it a Boolean value or a custom object.
How can I do this? At the moment I am using a file to log all names, which is horrible. This is the code so far:
def file
;LIBRARY
; Def file
EXPORTS
InstallHook
UninstallHook
dllapi.h
void InstallHook(void);
void UninstallHook(void);
dllmain.cpp
#include "stdafx.h"
using namespace std;
HINSTANCE currentProcessHandle;
HHOOK hookID;
string str = "1";
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call,LPVOID lpReserved)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
currentProcessHandle = hModule;
return TRUE;
}
LRESULT CALLBACK HookProcedure(int nCode, WPARAM wparam, LPARAM lparam)
{
if (nCode < 0) return CallNextHookEx(hookID, nCode, wparam, lparam);
std::ofstream outfile;
CBT_CREATEWND *CBTHOOKCREATE;
RECT *CBTRECTPTR;
RECT CBTRECT;
wstring Message;
CBTHOOKCREATE = (CBT_CREATEWND*) lparam;
LPWSTR str = L" ";
outfile.open(("d:\\test.txt"), std::ios_base::app);
if (nCode >= 0) {
switch (nCode)
{
case HCBT_CREATEWND:
outfile << *(CBTHOOKCREATE->lpcs->lpszName) << " " << CBTHOOKCREATE->lpcs->lpszName << " Created!~ " << endl;
//cout << "Created!~" << endl;
break;
case HCBT_DESTROYWND:
outfile << "Destroyed!~" << endl;
//cout << "Destroyed!~" << endl;
break;
default:
//cout << "something else" << endl;
break;
}
}
outfile.close();
return 0;
}
void InstallHook(void)
{
hookID = SetWindowsHookEx(WH_CBT, HookProcedure, currentProcessHandle, 0);
}
void UninstallHook(void)
{
UnhookWindowsHookEx(hookID);
}
Hook Consumer console application
// Hook Executer.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "..\Dll\dllapi.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int num = -1;
cout << "1.Install Hook"<<endl
<< "2.Unistall Hook"<<endl
<< "0.Exit";
do{
cin >> num;
if (num ==1)
{
InstallHook();
}
else
{
UninstallHook();
}
getchar();
system("cls");
cout << "1.Install Hook" << endl
<< "2.Unistall Hook" << endl
<< "0.Exit";
} while (num != 0 && num < 3);
return 0;
}
The Hook DLL is loaded, by Windows, in the address spaces on the hooked processes. You will have to use IPC. See Interprocess Communications for a starter.
One simple IPC, usable in such a case, may be Data Copy.
Note that Data Copy requires an active (pumped) message queue in the receiving thread.
One possible way to implement that (many others possible):
You add a secondary thread to your EXE, with a pumped message queue. In the new thread, you will create a dummy invisible windows, with a specific class name.
The code for that is a very classic sequence: RegisterClass, CreateWindow, while GetMessage DispatchMessage
In the Hook DLL, you will have a global HWND variable. When wanting to use WM_COPYDATA, if the global variable is null, use FindWindow to retrieve the HWND, and store it for next use. That code will be executed a least one time in each hooked process.
You may want to use the SendMessageTimeout API to send the WM_COPYDATA message.
Note that if you stop/restart your exe quickly, some processes may have an invalid HWND stored in the global variable. Check the return value of the Send API, and if it's "invalid hwnd", redo the FindWindow. (not sure if that's kind of behavior is really possible, but anyway...)
Also note, that your main thread should wait for the correct creation of the dummy window in the secondary thread before installing the hook.
If your hooking EXE is a Windowed one, you don't need a secondary thread, but you will have to build a GUI. You could also, perhaps, stay with "only one thread" and manage to juggle with some APIs, to have at the same time an active message queue and your getchar code, but I don't recommend that.
I'm trying to create a simple non-blocking timer in C++ that can be reset. I've google searched for a while to find some code examples but everything I find is either too complicated to understand or does not compile without extra non example code.
I have a program that logs a key press to a file, but I want this file to be written over one seconds after the key has been pressed unless another key has been pressed before the second is up.
I believe I should use Win32 timers, (I am using windows) however I can't find a simple compilable example of their use.
for example this method taken from the info page:
SetTimer(hwnd, // handle to main window
IDT_TIMER1, // timer identifier
1000, // 1-second interval
(TIMERPROC) MyTimerProc); // no timer callback
VOID CALLBACK MyTimerProc(
HWND hwnd, // handle to window for timer messages
UINT message, // WM_TIMER message
UINT idTimer, // timer identifier
DWORD dwTime) // current system time
{
// my proceedure code
FILE *OUTPUT_FILE;
OUTPUT_FILE = fopen("LOG.TXT", "w");
fprintf(OUTPUT_FILE, "%s", "");
fclose(OUTPUT_FILE);
// writes a blank text file.
KillTimer(hwnd, IDT_TIMER1); // stop timer after one call
}
doesn't compile because the IDT_TIMER1 hasnt' been defined I think.
Also, I'm not sure if this would be reset by calling it twice or would just start two separate calls 1 second apart.
Any help greatly appreciated.
Just use the Hardware Performance Timer, which can be quickly found via google, or if you want something more cross platform use the timegettime method, which can also be found via google, neither need a Win32 message loop.
You are responsible for giving ID_TIMER1 a value. I believe you (99%) also have to have a windows message loop for it to work.
Here are a couple of minimal, compilable examples.
The following console program works. It sets a timer using SetTimer
then loops in a message loop. The message loop receives and processes WM_TIMER messages
and the timer callback also is called for each time interval. And it does not block.
#define STRICT 1
#include <windows.h>
#include <iostream.h>
VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
cout << "Time: " << dwTime << '\n';
cout.flush();
}
int main(int argc, char *argv[], char *envp[])
{
int Counter=0;
MSG Msg;
UINT TimerId = SetTimer(NULL, 0, 500, &TimerProc); //SetTimer
cout << "TimerId: " << TimerId << '\n';
if (!TimerId)
return 16;
while (GetMessage(&Msg, NULL, 0, 0))
{
++Counter;
if (Msg.message == WM_TIMER)
cout << "Counter: " << Counter << "; timer message\n";
else
cout << "Counter: " << Counter << "; message: " << Msg.message << '\n';
DispatchMessage(&Msg);
}
KillTimer(NULL, TimerId);
return 0;
}
You don't need a window or even an event loop. Look at the WaitForSingleObject function.
Here is some code
HANDLE hStdin;
hStdin = GetStdHandle(STD_INPUT_HANDLE);
FILE *OUTPUT_FILE;
OUTPUT_FILE = fopen("LOG.TXT", "w");
bool previous_input_written = TRUE;
switch (WaitForSingleObject(hStdin, 1000) {
case WAIT_OBJECT_0:
// input happened on hStdin
if (!previous_input_written) {
// the previous input was not saved to file
fprintf(OUTPUT_FILE, ...
previous_input_written= TRUE;
}
ReadConsoleInput(hStdin, ...
previous_input_written = FALSE;
case WAIT_TIMEOUT:
// the 1000ms delay timed out, write to file
fprintf(OUTPUT_FILE, ...
previous_input_written= TRUE;
}
fclose(OUTPUT_FILE);
I've been trying to write an application, using Qt and mingw32, to download images and set them as the background Wallpaper. I have read several articles online about how to do this, in VB and C#, and to some extent how to do it in c++. I am currently calling the SystemParametersInfo with what seems to be all the correct arguments (no compiler errors) and it fails. No great crash of cymbals, just a 0 returned. GetLastError() returns an equally enlightening 0.
Below is the code I am using (In a slightly modified form, so you do not have to view the object internals).
#include <windows.h>
#include <iostream>
#include <QString>
void setWall()
{
QString filepath = "C:\\Documents and Settings\\Owner\\My Documents\\Wallpapers\\wallpaper.png";
char path[150];
strcpy(path, currentFilePath.toStdString().c_str());
char *pathp;
pathp = path;
cout << path;
int result;
result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, pathp, SPIF_UPDATEINIFILE);
if (result)
{
cout << "Wallpaper set";
}
else
{
cout << "Wallpaper not set";
cout << "SPI returned" << result;
}
}
It could be that SystemParametersInfo is expecting an LPWSTR (a pointer to wchar_t).
Try this:
LPWSTR test = L"C:\\Documents and Settings\\Owner\\My Documents\\Wallpapers\\wallpaper.png";
result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, test, SPIF_UPDATEINIFILE);
If this works (try it with a few different files just to make sure), you'll need to convert your char * to a LPWSTR. I'm not sure if Qt offers these services, but one function that may help is MultiByteToWideChar.
"C:\Documents and Settings\Owner\My Documents\Wallpapers\wallpaper.png";
shouldn't this be:
"C:\\Documents and Settings\\Owner\\My Documents\\Wallpapers\\wallpaper.png";
You cn use SetTimer to trigger a change.
#define STRICT 1
#include <windows.h>
#include <iostream.h>
VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
LPWSTR wallpaper_file = L"C:\\Wallpapers\\wallpaper.png";
int return_value = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, wallpaper_file, SPIF_UPDATEINIFILE);
cout << "Programmatically change the desktop wallpaper periodically: " << dwTime << '\n';
cout.flush();
}
int main(int argc, char *argv[], char *envp[])
{
int Counter=0;
MSG Msg;
UINT TimerId = SetTimer(NULL, 0, 2000, &TimerProc); //2000 milliseconds
cout << "TimerId: " << TimerId << '\n';
if (!TimerId)
return 16;
while (GetMessage(&Msg, NULL, 0, 0))
{
++Counter;
if (Msg.message == WM_TIMER)
cout << "Counter: " << Counter << "; timer message\n";
else
cout << "Counter: " << Counter << "; message: " << Msg.message << '\n';
DispatchMessage(&Msg);
}
KillTimer(NULL, TimerId);
return 0;
}