[c++/mingw/winapi] zmiana tapety

0

witam, z góry zaznaczam, że w życiu nie napisałem ani kawałka kodu korzystając z winapi, zatem wybaczcie moje kompletne niezrozumienie tego "api".
otóż potrzebuję na windowsie zmienić tapetę - problem polega na tym, że przykłady podane w necie nie działają. ma msdn znalazłem coś takiego, http://msdn.microsoft.com/en-us/library/bb776357(VS.85).aspx, problem polega na tym, że shlobj.h z mingw takiej struktury nie zawiera. jak zatem się za to zabrać?

0

a takie coś:

   SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "c:\\plik.bmp",
   SPIF_UPDATEINIFILE || SPIF_SENDWININICHANGE);

//EDIT Hym działa tylko z bmp , nie chce mi się instalować Ming

z mingw takiej struktury nie zawiera

struktury [???]
Nie zawiera czego ? Może .lib (.a, .o) trzeba dołączyć,,,
Myślę że deklaracja SetWallpaper jest w shlobj.h.
Podaj jakie błędy daje kompilator.

0

ech
czym to jest jak nie struktura? w shlobj.h z mingw w ogole nie ma takiego symbolu, bledow nie chce mi sie przeklejac bo to klasyczne "IActiveDesktop was not declared in this scope", a te windowsowe terminale sa strasznie lewe

0

Więc może w tym Ming są stare wer. bibliotek w msdn
http://msdn.microsoft.com/en-us/library/bb776357(VS.85).aspx
jest :
Minimum DLL Version shell32.dll version 4.71 or later
co jest powiązane z deklaracjami w plikach .h

0

w standardowych plikach Dev C++ po zainstalowaniu deklaracji IActiveDesktop nie ma, może stara wersja, a może po poprstu uznali że to niepotrzebny stuff, w VC++ 2008 mam ten interfejs...

IActiveDesktop to żadna struktura tylko interfejs obiektu COM, w msdn masz napisane jak to tworzyć( CoCreateInstance z odpowiednim CLS, wszystko masz podane)...

0

przeglądałem nagłówki z msvc++ i tam to jest struktura. mam najnowszą wersję mingw, mimo to nie mam jej w nagłówkach. podejrzewam, że to jest po prostu Not Yet Implemented. szkoda. nie ma jakiś innych sposobów, które działają z popularnymi formatami?

0

swego czasu też używałem Dev C++, który ma tę wersję plików WinAPI z Mingw i także zauważyłem, że pewnych rzeczy nie ma, które w VC++ są...

Ale to dotyczy ściśle specyficznych rzeczy, rzadko używanych, ja pamiętam, że jak robiłem coś tam z multimediami(odtwarzanie dźwięku o ile pamiętam) potrzebowałem chyba też jakiegoś COM, nie było, tzn było ale nie całkiem :> nie wszystko co być powinno, tak to już jest, lepiej używać bibliotek VC++

0
#define _WIN32_WINNT 0x0500
#define _WIN32_IE 0x600
#include <windows.h>

// next two are for ActiveDesktop and IE stuff
#include <winuser.h>
#include <WININET.H>
#include <shlobj.h>
#include "shlwapi.h"
#include <tchar.h>
#include <string>
#include <iostream>
using namespace std;


class CRegistry
{
private:
	static void DisplayErrorMessage(string cstrMethodName)
	{
		LPVOID lpMsgBuf;
		string cstrCaption;

		if (GetLastError() != 0)
		{
			char buf[255];
			sprintf(buf,"Utility Class Error in %s (%d)", cstrMethodName.c_str(), GetLastError());

			FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | 
				FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), 
				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
				0, NULL);

			MessageBox(NULL,(const char*)lpMsgBuf, cstrCaption.c_str(), MB_OK);
		}
	};

public:
	// Get a DWORD value from the registry
	static DWORD GetRegDWORD(string cstrKeyName, string cstrValueName, 
		DWORD dwDefault = 0, HKEY hBaseKey = HKEY_CURRENT_USER)
	{
		HKEY hKey;
        DWORD dwBufLen = sizeof(DWORD);
		DWORD dwReturn = dwDefault;
		BOOL bError = TRUE;

        if (RegOpenKeyEx(hBaseKey, cstrKeyName.c_str(), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
		{
			if (RegQueryValueEx(hKey, cstrValueName.c_str(), NULL, NULL, (LPBYTE) &dwReturn, &dwBufLen) == ERROR_SUCCESS) 
				bError = FALSE;

			RegCloseKey(hKey);
		}
	
		if (bError) DisplayErrorMessage("GetRegDWORD");

		return dwReturn;
	};

	// Set a DWORD value in the registry
	static void SetRegDWORD(string cstrKeyName, string cstrValueName, DWORD dwValue, 
		HKEY hBaseKey = HKEY_CURRENT_USER)
	{
		HKEY hKey;
		LONG lRet;
		BOOL bError = TRUE;

		lRet = RegOpenKeyEx(hBaseKey, cstrKeyName.c_str(), 0, KEY_SET_VALUE, &hKey);
        if (lRet != ERROR_SUCCESS)
			lRet = RegCreateKeyEx(hBaseKey, cstrKeyName.c_str(), 0, "", 0, KEY_READ | KEY_WRITE, NULL, &hKey, NULL); 
		
		if (lRet == ERROR_SUCCESS)
		{
			if (RegSetValueEx(hKey, cstrValueName.c_str(), NULL, REG_DWORD, (LPBYTE) &dwValue, sizeof(DWORD)) == ERROR_SUCCESS)
				bError = FALSE;

			RegCloseKey(hKey);
		}

		if (bError) DisplayErrorMessage("SetRegDWORD");
	};

	// Get a string value from the registry
	static string GetRegString(string cstrKeyName, string cstrValueName, 
		string cstrDefault = "", HKEY hBaseKey = HKEY_CURRENT_USER)
	{
		HKEY hKey;
        char szValue[MAX_PATH + 1];
		string cstrReturn = cstrDefault;
		DWORD dwBufLen = MAX_PATH + 1;
		BOOL bError = TRUE;

        if (RegOpenKeyEx(hBaseKey, cstrKeyName.c_str(), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
		{
			if (RegQueryValueEx(hKey, cstrValueName.c_str(), NULL, NULL, (LPBYTE) szValue, 
				&dwBufLen) == ERROR_SUCCESS)
			{
				cstrReturn = szValue;
				bError = FALSE;
			}

			RegCloseKey(hKey);
		}

		if (bError) DisplayErrorMessage("GetRegString");

		return cstrReturn;
	};

	// Set a string value in the registry
	static void SetRegString(string cstrKeyName, string cstrValueName, string cstrValue, HKEY hBaseKey = HKEY_CURRENT_USER)
	{
		HKEY hKey;
		LONG lRet;
		BOOL bError = TRUE;

		lRet = RegOpenKeyEx(hBaseKey, cstrKeyName.c_str(), 0, KEY_SET_VALUE, &hKey);
        if (lRet != ERROR_SUCCESS)
			lRet = RegCreateKeyEx(hBaseKey, cstrKeyName.c_str(), 0, "", 0, KEY_READ | KEY_WRITE, NULL, &hKey, NULL); 
		
		if (lRet == ERROR_SUCCESS)
		{
			if (RegSetValueEx(hKey, cstrValueName.c_str(), NULL, REG_SZ, 
					(const unsigned char*)cstrValue.c_str(), cstrValue.length()) != ERROR_SUCCESS)
				bError = FALSE;

			RegCloseKey(hKey);
		}

		if (bError) DisplayErrorMessage("SetRegString");
	};

	// Delete a value or key from the registry
	static BOOL RegDelete(string cstrKeyName, string cstrValueName = "", string cstrSubKeyName = "", 
		HKEY hBaseKey = HKEY_CURRENT_USER)
	{
		HKEY hKey;
		BOOL bRetVal = FALSE;
		BOOL bError = TRUE;

		if (RegOpenKeyEx(hBaseKey, cstrKeyName.c_str(), 0, KEY_WRITE, &hKey) == ERROR_SUCCESS)
		{
			if (cstrValueName.length())
			{
				// delete a value
				if (RegDeleteValue(hKey, cstrValueName.c_str()) == ERROR_SUCCESS)
				{
					bRetVal = TRUE;
					bError = FALSE;
				}
			}
			else
			{
				if (cstrSubKeyName.length())
				{
					// delete an entire key
					if (SHDeleteKey(hKey, cstrSubKeyName.c_str()) == ERROR_SUCCESS)
					{
						bRetVal = TRUE;
						bError = FALSE;
					}
				}
			}

			RegCloseKey(hKey);
		}

		if (bError) DisplayErrorMessage("RegDelete");

		return bRetVal;
	}
};

//decleare this variable in the .h file//
IActiveDesktop* pIActiveDesktop;
//////////////////////////////////////////

enum { tiled = 0, centered, stretch };

int main()
{
	int iPosition = stretch;

	string cstrTileWallpaper = "C:\\WINDOWS\\Web\\Wallpaper\\ascent.jpg"; 
	string cstrWallpaperStyle;
	TCHAR szBuf[MAX_PATH];

	pIActiveDesktop = NULL;

	CoInitialize(NULL);

	HRESULT hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, 
		IID_IActiveDesktop, (void**) &pIActiveDesktop);

	if (FAILED(hr))
		pIActiveDesktop = NULL;

	// If Active Desktop is not available, use the SystemParametersInfo function.
	if (pIActiveDesktop == NULL)
	{
			if (iPosition == 0)
			{
				// Tiled
				cstrTileWallpaper = "1";
				cstrWallpaperStyle = "1";
			}
			else if (iPosition == 1)
			{
				// Center
				cstrTileWallpaper = "0";
				cstrWallpaperStyle = "1";
			}
			else
			{
				// Stretch
				cstrTileWallpaper = "0";
				cstrWallpaperStyle = "2";
			}

			// Set registry values for the wallpaper position.
			CRegistry::SetRegString("Control Panel\\Desktop", "TileWallpaper", cstrTileWallpaper);
			CRegistry::SetRegString("Control Panel\\Desktop", "WallpaperStyle", cstrWallpaperStyle);

			// Change the wallpaper.
			SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)szBuf, 
				SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);	
		}
		else
		{
			WALLPAPEROPT wpOptions;
			COMPONENTSOPT compOptions;

			compOptions.dwSize = sizeof(COMPONENTSOPT);
			compOptions.fActiveDesktop = TRUE;
			compOptions.fEnableComponents = TRUE;

			pIActiveDesktop->SetDesktopItemOptions(&compOptions, 0);

			// Set the wallpaper position.
			wpOptions.dwSize = sizeof(WALLPAPEROPT);
			if (iPosition == 0)
				wpOptions.dwStyle = WPSTYLE_TILE;
			else if (iPosition == 1)
				wpOptions.dwStyle = WPSTYLE_CENTER;
			else
				wpOptions.dwStyle = WPSTYLE_STRETCH;

			pIActiveDesktop->SetWallpaperOptions(&wpOptions, 0);

			// Set the wallpaper image.
			int len = cstrTileWallpaper.length()+1;
			wchar_t* tbuf = new wchar_t[len];
			mbstowcs(tbuf,cstrTileWallpaper.c_str(),len);
			pIActiveDesktop->SetWallpaper(tbuf, 0);
			delete[] tbuf;

			// Apply all changes.
			pIActiveDesktop->ApplyChanges(AD_APPLY_ALL);
		}
	CoUninitialize();
	return 0;
}
0

Je,, dzizus 8-O tyle kodu do zmiany tapety ... uuuu

0

Dużo i nie dużo. 20 linijek do zmiany tapety przez ActiveDesktop, 10 linijek do zmiany tapety przez SystemParametersInfo, reszta to obsługa rejestru. Jeśli darować by sobie starsze Windowsy to zostaje tylko te 20 linijek ActiveDesktop. Trzeba wywołać 2 metody interfejsu COM.

0

Odświeżę trochę temat zmiany tapety. W SystemParametrsInfo() podaję ścieżkę dostępu jako "1.bmp" aby plik został odczytany z folderu z programem. Niestety, dalej odczytuje on plik z dysku c:, jak mam zrobić aby to zadziałało. W przypadku plików .txt powyższy sposób działał, ale w tej funkcji nie chce.

0

Musisz podać pełną ścieżkę. Zresztą dziś już bym zrezygnował z SystemParametersInfo (jedyne rozwiązanie na Win98) i użył wyłącznie ActiveDesktop (AFAIK zadziała od Windows ME).

1 użytkowników online, w tym zalogowanych: 0, gości: 1