2013-02-03 1 views
0
#include <iostream> 
#include <windows.h> 
using namespace std; 

int main(){ 
    LPWSTR test = L"c:/aizen.png"; 
    int result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, test, SPIF_UPDATEINIFILE); 
    if(result) 
     cout << "Wallpaper set!"; 
    else 
     cout << "Error: " << GetLastError(); 
    cin >> result; 
    return 0; 
} 

이 코드는 배경 무늬 벽지를 변경하기위한 것일 뿐이지 만 오류 : 2는 "파일을 찾을 수 없음"을 의미합니다. 그러나 파일이 있습니다! 나는 2010 년 Microsoft Visual Studio를 사용하고 있으며 관리자, 대소 문자 구분, 변경 슬래시 등으로 실행 해 보았습니다. 무엇이 잘못 되었나요?GetLastError는 SystemParametersInfo에서 오류 2를 반환합니다.

+0

: /가 ?? C : \\ aizen.png로 변경하십시오 –

+0

신중하게 질문을 읽으십시오 : 나는 이것을 시도했지만 제대로 작동하지 않는다고 말했습니다. – jzeus

+1

UNICODE가 정의되어 있습니까? 그렇지 않으면 Unicode 문자열을 사용하여 ANSI 버전의 SystemParametersInfo를 호출하게되므로 결국 파일 이름을 "c"로 처리하게됩니다 ... SystemParamatersInfo는 pvParam이 void *이므로 까다 롭습니다. 따라서 아무 것도 없습니다. CHAR vs WCHAR 유형 검사. 강하게 유형이 지정된 다른 API에서 얻을 수 있습니다. Unicode 버전 인 SystemParamtersInfoW를 명시 적으로 호출 해보십시오. – BrendanMcK

답변

2

오류 2는 File not found입니다.

먼저 aizen.png이 드라이브 C:\의 루트 폴더에 있는지 확인하십시오 (비 관리자 사용자에게는 일반적으로 쓰기 권한이없는 경우 Vista 이상은 해당되지 않습니다). 그것은 실제로 이것을 당신이는 MinGW의 C++ 컴파일러로 컴파일하는 경우와 같은 매우 이상한 모양을 컴파일 것

LPWSTR test = L"c:\\aizen.png"; 
+0

질문을주의 깊게 읽으십시오 : 나는 이것을 시도했지만 잘 풀지 못했다고 말했습니다. – jzeus

+1

귀하의 질문에 "슬래시를 변경하려고했습니다"라고 표시됩니다. 적절한 해결책 인 백 슬래시를 벗어나는 것에 대해서는 아무 것도 말하지 않습니다. 그래도 작동하지 않으면 파일은 생각하는 곳에 존재하지 않습니다. –

+0

@DarrenSadr, Ken이 말했듯이, 당신의 파일은 그 이름으로 C 드라이브에 위치해 있지 않습니다. b) 백 슬래시를 제대로 벗어났습니다. 모든 것을 한번 더 확인하십시오 –

-1

: 파일이 실제로 존재하는 경우

, 문제는 제대로 탈출하지 백 슬래시를 걸 가능성이 높습니다 변화의 비트 :

int main(){ 
     int result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)"c:/aizen.jpg", SPIF_UPDATEINIFILE); 

이 일 것이고, 분명히 LPWSTR은 비주얼 스튜디오 아마 권한 문제가되었다 ...되지 않습니다. Admin으로 실행하고 다시 시도하십시오.

+0

흠, 나는 downvote하지 않았다. 그리고 그들이 그렇게하고있는 이유를 말하지 않기 때문에 downvoter에 수치. 어쨌든 문제는 유니 코드 문자열로 ANSI 함수를 호출 했으므로 실패한 것 같습니다. 이제 ANSI 문자열을 사용하여 ANSI 함수를 호출하므로 작동합니다. 더 나은 해결 방법은 wide/unicode 문자열을 사용하여 wide/unicode 함수를 호출하는 것입니다. 자세한 설명은 내 대답을 참조하십시오. – BrendanMcK

+0

이해가 안됩니다. 답이 무엇이 잘못 되었나요? 그것은 올바른 코드와 나를 위해 일한 솔루션을 제공합니다. – jzeus

+0

당신의 대답에 대한 몇 가지 가능한 문제점; 이 문제는 "매우 이상한"것이 아니며 LPWSTR이 더 이상 사용되지 않으며 권한 문제와 관련된 문제가 없습니다. 원래 코드가 작동하지 않는 이유와 여기에서 변경 한 이유에 대한 설명을 보려면 내 대답을 읽으십시오. 코드를 작성하는 것은 일을하는 것처럼 보일 때까지 일을 변경하는 것 이상입니다. 일이 왜 작동하지 않거나 일하는가에 대한 이해를 갖는 것이 중요합니다. – BrendanMcK

1

문제는 UNICODE 문자열 (LPWSTR)을 ANSI를 사용하는 API에 전달하는 것입니다.

거의 모든 Win32 API (모두 문자열을 가져옵니다)는 ANSI (8 비트 문자)의 경우 A, Wide ...의 경우 W로 끝나는 두 가지 버전으로 나뉩니다 -char, 일명 유니 코드 (기술적으로는 '진짜'유니 코드는 아니지만,이 답안에 더 가치가 있습니다.)

컴파일 시간에 UNICODE #define d가있는 경우, 일반 unadorned 버전은 #W ... 버전으로 정의됩니다. 그렇지 않으면 #define이 ... 버전이됩니다. winuer.h 한 번 봐, 그리고 당신은 볼 수 있습니다 : Windows가 SystemParametersInfo 기능을 가지고

WINUSERAPI 
BOOL 
WINAPI 
SystemParametersInfoA(
    __in UINT uiAction, 
    __in UINT uiParam, 
    __inout_opt PVOID pvParam, 
    __in UINT fWinIni); 
WINUSERAPI 
BOOL 
WINAPI 
SystemParametersInfoW(
    __in UINT uiAction, 
    __in UINT uiParam, 
    __inout_opt PVOID pvParam, 
    __in UINT fWinIni); 
#ifdef UNICODE 
#define SystemParametersInfo SystemParametersInfoW 
#else 
#define SystemParametersInfo SystemParametersInfoA 
#endif // !UNICODE 

참고; W는 넓은 LPWSTR을 기대하고 A는 보통 LPSTR을 기대한다. UNICODE가 정의되어 있는지 여부가 '기본값'인지 여부를 선택합니다. (항상 수동으로 A 또는 W를 추가하여 명시 적으로 호출 할 수도 있습니다.)

원래 코드에서 발생할 수있는 현상은 UNICODE가 정의되어 있지 않기 때문에 다음과 같은 결과를 초래할 수 있다는 것입니다. ANSI 문자열이지만 UNICODE 문자열을 전달하고 있으므로 작동하지 않습니다. 당신이 만든 "변화의 비트가"이 작업을하려면

은 조금 이상이다 : 그것은 잘 작동 있도록 이제 API의 ... 버전에 ANSI 문자열을 전달하는 :

int result = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, L"c:\\aizen.jpg", SPIF_UPDATEINIFILE); 

를 또는, "..."당신의 앱 사용 L의 시작에 문자열을 유니 코드를 정의 할 수 있으며, 일반 버전 : 또는

int result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)"c:/aizen.jpg", SPIF_UPDATEINIFILE); 

, 당신은 LPWSTR로 명시 적으로 W 버전을 호출 할 수 있습니다 #include 앞에 #define UNICODE를 원래 앱 상단에 추가하십시오. (UNICODE는 코드에서 명시 적으로 정의되는 대신 메이크 파일이나 컴파일러 설정 옵션에서보다 일반적으로 정의됩니다. 따라서 Win32 프로그래밍을 처음 사용하는 경우 놀라운 기능으로 나타날 수 있습니다.)

LPWSTR은 이 아니며이 아닙니다. 무엇이라도 그것은 반대입니다. XP 이후의 전형적인 Win32 연습은 전 체 W- 풍미 문자열을 사용하기 때문에 Win32에서 "비추천"된 것으로 간주되는 일반 "..."문자열입니다. (예를 들어, 많은 COM API는 넓은 문자열 만 사용합니다.)

대부분의 다른 함수는 이에 대한 보호 기능을 가지고 있습니다. 실수로 SetWindowTextW라고 말하는 ANSI 문자열을 전달하려고하면 전달중인 LPSTR이 함수가 예상하는 정규화 된 LPWSTR 유형과 일치하지 않기 때문에 컴파일 타임 오류가 발생합니다. 그러나 SystemParamtersInfo는 까다 롭습니다. 데이터 매개 변수에 void *가 필요하므로 컴파일시에 [거의] 의 어떤 것도을 받아 들일 것이고 런타임에 함수를 호출 할 때만 오류가 발생합니다.

-

이, 그런데, 다윗 Herfernan가 answer to your question the first time you posted에서 지적한 것입니다 - C 무엇

Some possible causes spring to mind:
...
  • You have an ANSI/Unicode encoding mismatch.
관련 문제