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ć?

- Rejestracja:około 19 lat
- Ostatnio:prawie 16 lat

- Rejestracja:ponad 18 lat
- Ostatnio:prawie 12 lat
- Postów:787
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.

- Rejestracja:ponad 18 lat
- Ostatnio:prawie 12 lat
- Postów:787
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
- Rejestracja:ponad 17 lat
- Ostatnio:ponad 15 lat
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)...
- Rejestracja:ponad 17 lat
- Ostatnio:ponad 15 lat
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++

- Rejestracja:ponad 21 lat
- Ostatnio:około 12 lat
#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;
}

- Rejestracja:ponad 21 lat
- Ostatnio:około 12 lat
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.
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.
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.