WM_CHAR 提示手ra的2字節文字取得樣本 |
|
conundrum
尊榮會員 發表:893 回覆:1272 積分:643 註冊:2004-01-06 發送簡訊給我 |
"WMIME_CHAR. WM_CHAR @ Windows2000" http://forum.nifty.com/fdelphi/samples/01352.html 【 WM_CHAR 提示手ra的2字節文字取得樣本】 參閱 url 2001/06/27 現在。另起行拒絕 http://www.microsoft.com/japan/developer/windows2000/ technologies/ac-win2kcompat/ac-win32apichanges.asp Windows2000 上乘、WM_KEYDOWN 從 WM_KEYUP 到的間、meッ 洋蘇草的數據 WParam, LParam 開頭~作為不插叫做 話。(開頭~沙灘=數據更新=價代入) 上述 url 的記述的通、Windows2000 從親筆寫認識、聲音認識 支持 SendInput API 安裝れ、這 API 根據posu to做了鍵數據的 WParam 的 HiWord 那個數據進入井 、TranslateMessage API 模糊的數據支持正在做。就是 從、中途 WParam 更新於是遺憾是叫做事象是……。 【那個1】文字輸入時的TMemo 收提示 TMemo 「喂」$82A0 輸入稻田偶爾 TMemo 收集市一 zi出示。 #1 MessageID:WParam:LParam WM_IME_CHAR:000082A0:00000001 WM_CHAR:00000082:00000001 以下 win32.hlp WM_IME_CHAR 從的引用。 >Remarks > >If the WM_IME_CHAR message includes a double-byte character, >the DefWindowProc function converts this message into two >WM_CHAR messages, each containing one byte of the double-byte character. > 2字節文字含 WM_IME_CHAR 2個的 WM_CHAR 被改變真實 沙灘。實際在……中1字節文字也1個的 WM_CHAR 被改變。子女 苛刻、被改變的提示、提示尾白攢。 提示尾白關於、Delphi CD-ROM 有 Api32wh. slp 的「提示與提示 尾白的概要」的題目參 照請。 #1的結果上述記述與不同、1個的 WM_CHAR 隻有下次丁籬笆 。為何就是? 【那個2】首先 WM_IME_CHAR 「喂」文字取得 WParam $A0 更新那麼說來 Windows95, 98 這些市街的區劃 動作駿河、Windows2000 那個記載在下邊代碼利用人的meッ 洋蘇草尾白、靈巧記憶的搓 WM_CHAR 提示被襲擊 現象發生。以下樣本代碼 procedure TEditor.WMImeChar(var Msg: TMessage); var S: String; C: Char; begin if Msg.wParam > 255 then begin // 2字節文字 C := Chr(Msg.wParam); Msg.wParam := Msg.wParam shr 8; // 更新 S := Chr(Msg.wParam) C; end else // 1字節文字 if TWMChar(Msg).CharCode in [$20..$7E, $A0..$FF] then S := Chr(Msg.wParam); // Windows 的 DefWindowProc 根據 WM_CHAR 柱做 inherited; end; 【3.TMemo 的探求】 堵塞、WM_IME_CHAR IME 文字取得後面 WParam 開頭沙灘的是 禁止是。怎麼辦叫做事、TMemo 欺負 看出神。 SendMessage(Memo1.Handle, WM_IME_CHAR, $8E8E, 0); // 品酒 SendMessage(Memo1.Handle, WM_CHAR, $8F, 0); TMemo 在……中「品酒」$8E8E 不是「人民」$8F8E 被表示。 【4.miso】 SendMessage(Memo1.Handle, WM_IME_CHAR, $8E8E, 0); // 品酒 這時、WParam $8E 的 WM_CHAR 2個提示尾白po 罷工做。提示尾白攢提示、輔助動力裝置ri 鉀syon閒暇腹足類爐缸到被擱置因為、這時標點、uィ ndo過程不被處理。 SendMessage(Memo1.Handle, WM_CHAR, $8F, 0); 捆被實行的時、Memo1 WParam $8F 的 WM_CHAR 收。這時、TMemo 的 WM_CHAR 提示手ra (=Windows 的標準控制的 WM_CHAR 提示手 ra)、提示尾白正在攢是……吧其次的2字節眼 尾白從拿出、$8F 之外2字節文字作為處理。 堵塞「人民」被表示。 實驗看 表單筆記1個粘、那個 OnClick 集會手ra 以下的象記述。 procedure TForm1.Memo1Click(Sender: TObject); var I: Integer; begin // 念頭因為(為了)、提示尾白空洞 Application.ProcessMessages; // 「合適饑餓」的下位字節隻有提示尾白 // 攢 PostMessage(Memo1.Handle, WM_CHAR, $A0, 0); PostMessage(Memo1.Handle, WM_CHAR, $A2, 0); PostMessage(Memo1.Handle, WM_CHAR, $A4, 0); PostMessage(Memo1.Handle, WM_CHAR, $A6, 0); PostMessage(Memo1.Handle, WM_CHAR, $A8, 0); // 「合適饑餓」的上位字節隻有風過程 // 送安上 for I := 0 to 4 do SendMessage(Memo1.Handle, WM_CHAR, $82, 0); // 另起行 SendMessage(Memo1.Handle, WM_CHAR, $0D, 0); end; 合適饑餓另起行與筆記被表示。Windows2000 上乘也大 授予程度出。 【5.本日的題 WM_CHAR 根據2字節文字取得樣本】 procedure THoge.WMChar(var Message: TWMKey); var CH, CL: Char; M: TMsg; S: String; begin if Message.CharCode in [$20..$7E, $A0..$FF] then // 1字節文字 S := Chr(Message.CharCode) else begin // 2字節文字 CH := Chr(Message.CharCode); if (CH in LeadBytes) and PeekMessage(M, Handle, 0, 0, PM_NOREMOVE) and (M.Message = WM_CHAR) and (M.wParam in [$40..$FF]) and PeekMessage(M, Handle, 0, 0, PM_REMOVE) then begin CL := Chr(M.wParam); S := CH CL; end; end; end; **** 大田勝彥 http://member.nifty.ne.jp/~katsuhiko/ **** Original document by 大田勝彥 氏 ID:(VYR01647) 日文 ///////////////////////////////////////////////////////////////////////// "WMIME_CHAR. WM_CHAR @ Windows2000" 【 WM_CHAR メッセージハンドラでの2バイト文字取得サンプル】 参考 url 2001/06/27 現在。改行御免 http://www.microsoft.com/japan/developer/windows2000/ technologies/ac-win2kcompat/ac-win32apichanges.asp Windows2000 上では、WM_KEYDOWN から WM_KEYUP までの間、メッ セージのデータ WParam, LParam をちょ~してはいけないというお 話です。(ちょ~す=データを更新する=値を代入する) 上記 url の記述の通り、Windows2000 から手書認識、音声認識を サポートする SendInput API が実装され、この API によってポス トされたキーデータの WParam の HiWord にそのデータが入ってい て、TranslateMessage API もこのデータをサポートしている。だ から、途中で WParam を更新するといかんぜということらしいです。 【その1】文字入力時のTMemo が受け取るメッセージ TMemo に「あ」$82A0 を入力した時に TMemo が受け取るメッセー ジを示します。 #1 MessageID:WParam:LParam WM_IME_CHAR:000082A0:00000001 WM_CHAR:00000082:00000001 以下は win32.hlp WM_IME_CHAR からの引用です。 >Remarks > >If the WM_IME_CHAR message includes a double-byte character, >the DefWindowProc function converts this message into two >WM_CHAR messages, each containing one byte of the double-byte character. > 2バイト文字を含む WM_IME_CHAR は2個の WM_CHAR に変換されま す。実際には1バイト文字も1個の WM_CHAR に変換されます。こ こで、変換されたメッセージは、メッセージキューに溜まります。 メッセージキューについては、Delphi CD-ROM にある Api32wh. slp の「メッセージとメッセージ キューの概要」のトピックを参 照してください。 #1の結果は上記記述と違い、1個の WM_CHAR しか来ていませ ん。何故だ? 【その2】とりあえず WM_IME_CHAR で「あ」文字を取得し WParam を $A0 に更新してみると Windows95, 98 ではそれらしく 動作するが、Windows2000 でその下記コードを利用する人のメッ セージキューは、身に覚えのない WM_CHAR メッセージに襲われる 現象発生。以下サンプルコード procedure TEditor.WMImeChar(var Msg: TMessage); var S: String; C: Char; begin if Msg.wParam > 255 then begin // 2バイト文字 C := Chr(Msg.wParam); Msg.wParam := Msg.wParam shr 8; // 更新 S := Chr(Msg.wParam) C; end else // 1バイト文字 if TWMChar(Msg).CharCode in [$20..$7E, $A0..$FF] then S := Chr(Msg.wParam); // Windows の DefWindowProc により WM_CHAR がポストされる inherited; end; 【3.TMemo の探求】 つまり、WM_IME_CHAR で IME 文字を取得後 WParam をちょすのは 御法度であります。ではどうするかということで、TMemo をいじめ てみます。 SendMessage(Memo1.Handle, WM_IME_CHAR, $8E8E, 0); // 試 SendMessage(Memo1.Handle, WM_CHAR, $8F, 0); TMemo には「試」$8E8E ではなく「庶」$8F8E が表示されます。 【4.ミソ】 SendMessage(Memo1.Handle, WM_IME_CHAR, $8E8E, 0); // 試 この時、WParam が $8E の WM_CHAR が2個メッセージキューにポ ストされます。メッセージキューに溜まったメッセージは、アプリ ケーションが暇になるまで放置されますので、この時点では、ウィ ンドプロシージャで処理されません。 SendMessage(Memo1.Handle, WM_CHAR, $8F, 0); これが実行された時点で、Memo1 は WParam が $8F の WM_CHAR を 受け取ります。この時、TMemo の WM_CHAR メッセージハンドラ (=Windows の標準コントロールの WM_CHAR メッセージハンド ラ)は、メッセージキューに溜まっているだろう次の2バイト目を キューから取り出し、$8F に加え2バイト文字として処理します。 つまり「庶」が表示されます。 実験してみましょう フォームにメモを1個貼って、その OnClick イベントハンドラ を以下のように記述します。 procedure TForm1.Memo1Click(Sender: TObject); var I: Integer; begin // 念のため、メッセージキューを空にする Application.ProcessMessages; // 「あいうえお」の下位バイトだけをメッセージキューに // 溜める PostMessage(Memo1.Handle, WM_CHAR, $A0, 0); PostMessage(Memo1.Handle, WM_CHAR, $A2, 0); PostMessage(Memo1.Handle, WM_CHAR, $A4, 0); PostMessage(Memo1.Handle, WM_CHAR, $A6, 0); PostMessage(Memo1.Handle, WM_CHAR, $A8, 0); // 「あいうえお」の上位バイトだけをウィンドプロシージャに // 送りつける for I := 0 to 4 do SendMessage(Memo1.Handle, WM_CHAR, $82, 0); // 改行 SendMessage(Memo1.Handle, WM_CHAR, $0D, 0); end; あいうえお改行とメモに表示されます。Windows2000 上でもだい じょぶだそうです。 【5.本日のお題 WM_CHAR による2バイト文字取得サンプル】 procedure THoge.WMChar(var Message: TWMKey); var CH, CL: Char; M: TMsg; S: String; begin if Message.CharCode in [$20..$7E, $A0..$FF] then // 1バイト文字 S := Chr(Message.CharCode) else begin // 2バイト文字 CH := Chr(Message.CharCode); if (CH in LeadBytes) and PeekMessage(M, Handle, 0, 0, PM_NOREMOVE) and (M.Message = WM_CHAR) and (M.wParam in [$40..$FF]) and PeekMessage(M, Handle, 0, 0, PM_REMOVE) then begin CL := Chr(M.wParam); S := CH CL; end; end; end; **** 本田勝彦 http://member.nifty.ne.jp/~katsuhiko/ **** Original document by 本田勝彦 氏 ID:(VYR01647) |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |