2011-09-15 7 views
1

EDIT:以下に掲載されたワーキングコードは、ワーキングコードがコメントアウトされています。 Win7で作成したのと同じCHAR_Tを使用して、ウィンドウからデータを取得する必要があります。Win7のSendMessageAとSendMessageWはWinXPから移行されました

WinXPで完全に動作するダイアログがありますが、Win7ではunicodeのエディットコントロールからユーザー入力を収集できません。以下に示すような問題は、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. */ 
    } 
} 

SendMessageAがメッセージ= WM_GETTEXTまたはWM_SETTEXTで複数回作品現れ、突然、ワイド文字列が必要なとき、SendMessageWが失敗しました。さて、皆さんは、常にSendMessageを使ってCHAR_Tを選択してそれに固執すべきだと皆が考えていることを知っていますが、そうではありません。 Win32.hlpは、個々の関数を手動で呼び出すことにより、両方を同じプログラムで使用できることを明示的に示しています。他の誰かがコントロールそのものが特定のCHAR_Tにコミットしているとかコミットしていると言ってもいいですが、これは完全に機能するWinXPではそうではありません。その特定のエディットコントロールは、明示的にASCII文字列に設定されることもありません。

プログラムはWinHttpとやりとりし、WCHARのすべての文字列が必要です。それはSendMessageWが入る場所です。残りの入力は内部でのみ使用され、主に、ASCIIでより便利で効率的な単位ラベル付きの整数ですそれ以外の理由がない場合は、プログラムはもともとその方法で書かれていたからです。

だから何ですか?彼らは本当にSendMessageと一体不可分な何かを変えましたか?もしそうなら、それは回避策がある既知のバグですか、あるいは廃止予定の機能でCHAR_Tを切り替えることができますか? SendMessageAで取得した後、手動で入力をWCHARに拡張するより簡単な方法がありますか?

+0

私は、このエラーが 'SendMessageW()'にないと思っています。少なくとも出発点として。 'hDomainEdit'が有効ですか? 'SendMessageA'を使うとどうなりますか?また、なぜ 'GetWindowText [AW]'を使わないのですか? – atzz

+0

sayeth MSDN: "対象のウィンドウが現在のプロセスによって所有されている場合、GetWindowTextは指定されたウィンドウまたはコントロールにWM_GETTEXTメッセージを送信させます。それはほぼ同じ効果でなければなりません。私はハンドルの価値をチェックしようとします - それはその1つのステートメントの外で決して使用されないので、他のいくつかの問題は静かになるでしょう。しかし、それは間違いなくXPの正しいコントロールへの有効なハンドルです。 – sqykly

+0

私はここでWM_GETTEXTを使うのが間違っていると言っているわけではありません。個人的には、そうしなければならない理由がない限り、API関数をメッセージに使用する方が好きです。また、MSDNはGetWindowTextがWM_GETTEXTを送信する以外に何かを行うかどうかを示していません。例えば。いくつかのニュアンスがあるかもしれません。ANSI/UNICODE変換(私は覚えていませんが)。 – atzz

答えて

0

すべてのウィンドウハンドルは問題ありませんでした。 MSDNの人々は、 'A'関数(この場合はDialogBoxParamA())で作成されたウィンドウは、 'A'関数を介してアクセスする必要があることを伝えました。それがXPで働いたという事実に関して、彼らは「それが正しいということを意味するわけではない」と言った。私は機能が非難されたと思う - それが動作を停止する前にそれについて聞いていいだろう!

+0

あなたはそれについて聞いたことがあります。それはあなたがそれをやっているように働くことを決して意味しませんでした。あなたはちょうど幸運になりました。 MSは、公表されている仕様の範囲内にある図書館の実装の変更について誰にも知らせる義務はありません。 –

+0

@David Heffernan:この問題を具体的に記述した文書へのリンク?私はWindowsのデータ型の文字列やSendMessageのMSDN上では表示されません - 確かに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のUnicodeバージョンに登録されている場合、ウィンドウはUnicodeメッセージのみを受け取ります。ウィンドウがUnicode文字セットを使用するかどうかを判断するには、IsWindowUnicodeを呼び出します。 –

0

私が理解していることは、デバッガでコードをステップ実行すると、その理由がわかります。

まず、2つのSendMessagesが次々に存在し、異なるウィンドウハンドルを使用しているため、同じ結果を得ることはできません。さんがあなたに問題を与えてくれるものについてお話しましょう:

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

この行にデバッガに立ち、あなたのhDomainEdit変数を確認してください。おそらく、NULLのような有効ではない、あるいは他のコードによって損なわれているかもしれません。これは無効なハンドルとゼロの結果を説明します。

関連する問題