C++ launching program without console opening
Asked Answered
W

3

5

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!

Woadwaxen answered 5/10, 2012 at 13:18 Comment(0)
F
8

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.

Fillet answered 5/10, 2012 at 13:19 Comment(8)
I'm really new to c++ so when you say to use a WinMain entry point do I change 'int main() {' to 'int WinMain() {' or what? thanks!Woadwaxen
It's one of the options when creating a new project in Visual Studio. You can't just change the main signature and it magically becomes a Win32 app.Broddie
I don't use visual studio - I'm using Eclipse CDTWoadwaxen
This is incorrect. It doesn't matter if the launching program is a windows app or a console app. What matters is that the program being launched is console app.Brocket
@Brocket I didn't spot that system()! although actually both matter, the program will have to be a Win32 program in order to call SystemParametersInfo without creating a console window.Fillet
@Fillet - Console apps have full access to the Win32 API. No console window is needed or created.Brocket
@Brocket - Not an issue of access to the API, but console apps do always spawn a console window unless it's suppressed. See Konrad's answer: #575411, or just try it? Can you launch any console app from explorer without a console window appearing? (Unless you invoke them with "start" which suppresses the window by invoking CreateProcess with CREATE_NO_WINDOW)Fillet
@Fillet - Yes, I agree. I misunderstood when you said "both matter". I thought you were saying that a console app launching another console app would cause a new window to open.Brocket
B
7

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.

Brocket answered 5/10, 2012 at 14:48 Comment(3)
After adding this code and compiling I now get the error: 'Program too big to fit in memory'. I tried removing the code and recompiling but I still get the same error. Do you know how to fix this?Woadwaxen
I managed to fix the "program too big to fit in memory" error, but when I try to compile my program using your code it throws the error: "initializing argument 3 of 'BOOL SystemParametersInfoA(UINT, UINT, PVOID, UINT)' [-fpermissive]" with my code being "SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "Wallpaper.jpg", SPIF_UPDATEINIFILE);"Woadwaxen
My mistake. The third parameter needs to be cast to a PVOID.Brocket
F
2

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;
}
Footlocker answered 5/10, 2012 at 18:5 Comment(1)
About this ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false); approach, is the Window still there but hidden? Or does Windows really kills it?Parks

© 2022 - 2024 — McMap. All rights reserved.