2012-09-10 3 views
0

나는 팝업와 잘 작동 할 수있는 SHBrowseForFolder을 가지고,하지만 난 제목을 설정하고 싶습니다. 나는 그것이 wchar_t *이어야한다는 것을 알고 있고 (wchar_t *) L "My Title"과 같은 const를 사용할 때 제목이 정확하다는 것을 알 수있다. 나는 첫 번째 문자 'M'을 얻을 문자열 값을 사용하려고하면 넓은 문자열이 NUL로 각 문자를 pading, 다시 한 번 새로운 넓은 문자열로 변환 된 것처럼C++ 빌더 XE2 : wchar_t에 문자열로 변환하는 방법 *

는하지만, 그것은이다.

Winapi::Shlobj::BROWSEINFO bi = {0}; 
bi.hwndOwner = Handle; 
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_EDITBOX | BIF_BROWSEFORCOMPUTER; 
bi.lpszTitle = String("My Title").w_str(); // This only shows the 'M' 
//bi.lpszTitle = (wchar_t*)"My Title";  // This shows the full string 'My Title' 
LPITEMIDLIST pidl = SHBrowseForFolder((_browseinfoA*)&bi); 

if (pidl != 0) { 

    // free memory used 
    IMalloc *imalloc = 0; 
    if (SUCCEEDED(SHGetMalloc(&imalloc))) { 
    imalloc->Free(pidl); 
    imalloc->Release(); 
    } 
} 

UnicodeString 모든 변환 함수 c_str(), t_str()w_str() 모든 문서는 wchar_t* 반환하지만 선언은 WideChar*을 보여줍니다.

이 코드를 String과 함께 사용하는 방법에 대한 아이디어가 있으십니까?

답변

2

당신이 사실 타입 캐스팅 SHBrowseForFolder()를 호출하면 "_TCHAR지도를 위해"당신의 프로젝트 옵션에서 옵션 대신 "wchar_t를"의 "문자"로 설정되어 있는지 알려줍니다 때 _browseinfoA*bi 변수를. 즉, 귀하의 코드가 실제로 SHBrowseForFolderW() 대신 SHBrowseForFolderA()을 호출하고 있음을 의미합니다. XE2에서 _CHCH 설정과 관계없이 Winapi::Shlobj::BROWSEINFO 구조는 항상 ::BROWSEINFOW으로 매핑됩니다. BROWSEINFOW유니 구조가 아닌 ANSI 구조이다. 따라서 유니 코드 데이터를 Ansi 함수로 전달해야합니다. 네, 처음에는 잘못된 데이터를 전달하기 때문에 여분의 패딩이 데이터를 자릅니다.

캐스팅 사용을 중단해야합니다. 그들은 컴파일러에서 일반적으로 불평할만한 오류를 코드에 숨기고 있습니다. C/C++는 강력한 형식의 언어입니다. 형식 캐스트를 사용하면 컴파일러의 데이터 형식 유효성 검사가 무시됩니다.

1) 대신 Winapi::Shlobj 네임 스페이스의 글로벌 네임 스페이스에서 일반 BROWSEINFO 구조를 사용, 그래서 일반 SHBrowseForFolder() 함수의 인코딩과 일치 :

코드를 해결하려면, 당신도 할 필요가

::BROWSEINFO bi = {0}; 
bi.hwndOwner = Handle; 
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_EDITBOX | BIF_BROWSEFORCOMPUTER; 
bi.lpszTitle = TEXT("My Title"); 
LPITEMIDLIST pidl = SHBrowseForFolder(&bi); 
if (pidl != NULL) { 
    // free memory used 
    CoTaskMemFree(pidl); 
} 

2)는 Winapi::Shlobj 네임 스페이스에서 BROWSEINFO을 계속 사용하지만, 유니 코드 인코딩과 일치하는 대신 직접 SHBrowseForFolderW() 전화 :

을 당신이 가지고 접근에 상관없이 별도의 노트에

는, 당신은 제목 값으로 String 임시을 사용할 수 없습니다. StringSHBrowseForFolder()이 호출되기 전에 범위를 벗어나 BROWSEINFO::lpszTitle 필드가 유효하지 않은 메모리를 가리 키도록합니다. 당신이 다음 String를 사용하려면 당신은 예를 들어, 그것을 위해 지역 변수를 사용해야합니다 : 나는 SHBrowseForFolder() 함수의 넓은 문자 변형 생각하지 않았다

String sTitle = "My Title"; 
... 
bi.lpszTitle = sTitle.c_str(); 
+0

. 음, String은 간단한 코드 예제를 보여줄뿐입니다 ... 내 실제 코드는'bi.lpszTitle = Edit-> TextHint.w_str();'이며 설명과 함께 잘 작동합니다. 고맙습니다. –

+0

사용중인 임시 String 변수에 동일한 문제가 있습니다. 대신 명시 적 변수를 사용하십시오 :'String TextHint = Edit-> TextHint; bi.lpszTitle = TextHint.c_str(); ' –

+0

구현이 어떻게 문제가 될지 모르겠습니까? 'Edit'는 폼에 의해 생성 된 VCL 포인터이며 폼이 파기되지 않는 한 유효합니다. '에 의해 반환 된 포인터.w_str()'은 문자열을 조작하지 않는 한 유효합니다 (문서 관련). 'SHBrowseForFolderW'는 모달이므로 어쨌든 돌아올 때까지 아무 일도 일어나지 않을 것입니다. 어떻게 Edit-> Text.w_str()을 사용하는 것이 잘못 될 수 있습니까? –

관련 문제