2011-09-15 5 views
1

EDIT : 아래에 게시 된 작업 코드는 작업 코드가 주석 처리되었습니다. Win7에서 창을 생성 할 때 사용했던 창에서 데이터를 가져 오는 데 동일한 CHAR_T를 사용해야합니다.WinXP에서 SendMessageA 및 SendMessageW가 WinXP에서 마이그레이션되었습니다.

WinXP에서 완벽하게 작동하지만 Win7에서 유니 코드의 편집 컨트롤에서 사용자 입력을 수집하지 못하는 대화 상자가 C로 작성되었습니다. 아래 그림과 같이 문제는 SendMessageW에 대한 첫 번째 호출에 발생

/* handles to controls */ 
HWND hDomainEdit; 
HWND hOtherEdit; 
HWND hTextOut; 
HWND hButton; 
/* buffers to receive input */ 
WCHAR wszDomain[256]; 
CHAR szOtherInput[512]; 
CHAR szBuffer[512]; //added to hold temporary value of wszDomain 
/* a test string */ 
const CHAR szTest[] = "This is a test of SendMessageA." 

BOOL dialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { 

    if (message == WM_INIT) { 
     /* get all the handles shown above, then... */ 
     SendMessageA(hTextOut, WM_SETTEXT, 0, (LPARAM) szTest); 
     /* worked fine */ 
     /* do a few other things */ 
    } else if (message == WM_COMMAND) { 
     /* are some other conditions are true? they sure are */ 
     /* time to collect a bunch of input from controls */ 
     int cchResultLen = (int) SendMessageA(hOtherEdit, WM_GETTEXT, 512, (LPARAM) szOtherInput); 
     /* cchResultLen is correctly the length of the user input */ 
     /* cchResultLen = (int) SendMessageW(hDomainEdit, WM_GETTEXT, 256, (LPARAM) wszDomain); */ 
     /* begin new code */ 
     cchResultLen = (int) SendMessageA(hDomainEdit, WM_GETTEXT, 512, (LPARAM) szBuffer); 
     cchResultLen = MultiByteToWideChar(CP_UTF8, 0, szBuffer, cchResultLen, wszDomain, 256); 
     wszDomain[cchResultLen] = 0; /* above doesn't terminate string */ 
     /* after SendMessageW(), cchResultLen was 0, no string transferred, no error 
      message. using SendMessageA, all is well. */ 
    } 
} 

SendMessageW 대신 메시지 = WM_GETTEXT 또는 WM_SETTEXT, 넓은 문자열이 필요한 경우 갑자기, SendMessageW이 실패로 여러 번 작동이 나타납니다. 이제, 모든 사람들이 당신이 CHAR_T를 고르고 항상 SendMessage를 사용하여 고수해야한다고 생각하고 있습니다. Win32.hlp 명시 적으로 개별 프로그램을 수동으로 호출하여 같은 프로그램에서 둘 다 사용할 수 있습니다. 다른 사람이 컨트롤 자체가 하나의 특정 CHAR_T에 대해 커밋되거나 커밋 된 상태라고 말할 준비가되었지만 이것이 완벽하게 작동하는 WinXP에서는 그렇지 않습니다. 이 특정 편집 컨트롤도 ASCII 문자열로 명시 적으로 설정되지 않습니다.

이 프로그램은 모든 WCHAR 문자열을 필요로하는 WinHttp와 상호 작용하며 SendMessageW가 오는 곳입니다. 나머지 입력은 내부적으로 만 사용되며 주로 ASCII로 더 편리하고 효율적인 단위 라벨이있는 구문 분석 된 정수입니다 , 그 이유는 프로그램이 원래 그렇게 쓰여졌 기 때문 만은 아닙니다.

그럼 어떻게해야합니까? 그들은 실제로 SendMessage와 같이 필수적인 것을 호환되지 않는 것으로 변경 시켰습니까? 그렇다면, 알려진 버그일까요? 아니면 사용하지 않는 기능으로 CHAR_T를 전환 할 수 있습니까? SendMessageA로 가져온 후에 수동으로 입력을 WCHAR로 확장하는 것보다 쉬운 방법이 있습니까?

+0

오류가'SendMessageW()'에 없다고 생각합니다. 적어도 출발점으로. 'hDomainEdit'이 유효합니까? 'SendMessageA'를 쓸 때 어떻게됩니까? 또한'GetWindowText [AW]'를 사용하지 않으시겠습니까? – atzz

+0

sayeth MSDN : "대상 창을 현재 프로세스가 소유하고 있으면 GetWindowText가 WM_GETTEXT 메시지를 지정된 창이나 컨트롤로 보냅니다." 그래서 그것은 거의 같은 효과를 가져야합니다. 나는 핸들의 가치를 확인하려고 노력할 것입니다 - 그것은 한 문장의 외부에서 결코 사용되지 않기 때문에, 다른 문제는 침묵 할 것입니다. 그것은 XP에서 올바른 컨트롤에 대한 올바른 핸들입니다. – sqykly

+0

여기에 WM_GETTEXT를 사용하는 것이 잘못되었다고 말하는 것은 아닙니다. 개인적으로는 API 함수를 메시지에 사용하는 편이 더 좋을 것입니다. 또한 MSDN은 GetWindowText가 WM_GETTEXT를 보내는 것 외에 다른 작업을 수행하는지 여부를 나타내지 않습니다. 예 : 약간의 뉘앙스가있을 수 있습니다.ANSI/UNICODE 변환 (기억이 안나지만). – atzz

답변

0

모든 창 핸들이 좋았습니다. MSDN의 사람들은 'A'함수 (이 경우 DialogBoxParamA())로 생성 된 모든 윈도우는 'A'함수를 통해 액세스해야한다고 알려줍니다. XP에서 작동한다는 사실에 관해서는 "작동한다고해서 그것이 옳다는 것을 의미하는 것은 아닙니다."라고 그들은 말했습니다. 기능이 더 이상 사용되지 않을 것이라고 생각합니다. 작동을 멈추기 전에 그것에 대해 듣기 좋았을 것입니다!

+0

당신은 그것에 대해 듣고 그냥주의하지 않았습니다. 그것은 당신이 그 일을하는 방식대로 일한다는 의미가 아닙니다. 방금 운이 좋았어. MS는 게시 된 사양 내에있는 라이브러리의 구현 변경에 대해 누구에게도 알릴 의무가 없습니다. –

+0

@David Heffernan :이 문제를 구체적으로 설명하는 문서에 링크 하시겠습니까? MSDN의 String이나 SendMessage 용 Windows 데이터 형식에서는 볼 수 없습니다. Win32.hlp에서는 그렇지 않습니다. http://msdn.microsoft.com/en-us/library/dd317720%28v=VS.85%29.aspx – sqykly

+0

[About Windows] (http://msdn.microsoft.com)에 있습니다. /en-us/library/windows/desktop/ms632597(v=VS.85).aspx) 주제. "창 클래스가 유니 코드 버전의 RegisterClass에 등록 된 경우 창은 유니 코드 메시지 만받습니다. 창에서 유니 코드 문자 집합을 사용하는지 여부를 확인하려면 IsWindowUnicode를 호출하십시오." –

0

제 생각에 디버거로 코드를 단계별로 실행하면 그 이유를 알 수 있습니다.

우선, 두 개의 SendMessages가 차례로 있습니다. 다른 창 핸들을 사용하기 때문에 동일한 결과를 줄 수있는 종류가 아닙니다. 의 당신에게 문제를 제공하는 일에 대해 이야기 해 보자 :

cchResultLen = (int) SendMessageW(hDomainEdit, WM_GETTEXT, 256, (LPARAM) wszDomain); 
// cchResultLen is ZERO! wszDomain[0] is null. Edit control is not empty 

이 라인에 디버거 서, 당신의 hDomainEdit 변수를 확인합니다. 아마도 유효하지 않습니다. NULL이거나 다른 코드에 의해 손상되었습니다. 이것은 잘못된 핸들과 0 결과를 설명합니다.

관련 문제