全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1892
推到 Plurk!
推到 Facebook!

TEdit的WM_CHAR和中文字關係

尚未結案
Homi
一般會員


發表:19
回覆:23
積分:8
註冊:2003-07-26

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-02-23 14:43:14 IP:220.141.xxx.xxx 未訂閱
各位好: 我在Form上拉一個TEdit,把它原先的WndProc換成我自己的,想要攔下中文字的內碼,但是發現非常奇怪的現象。 部分的CODE的如下: 
void __fastcall TForm1::MyEditWndProc(TMessage & Message)
{
   int lParam=Message.LParam;
   int wParam=Message.WParam;       switch(Message.Msg)
   {
      //case WM_IME_CHAR:
      case WM_CHAR:
      {
        //add code to process wParam
      }
      break;
   }        OldEditWndProc(Message);
} 
發現,在Form的Edit上打 "我" 這個中文字(內碼為0xA7DA) 我用SPY 攔到的Message依序為: WM_CHAR wParam=0xDA (Lead byte) WM_CHAR wParam=0xA7 (trail byte) 但是我在我自己的程式裡攔到的Message為: WM_CHAR wParam=0xA7 就沒了 怎麼會這樣呢? 問題在哪裡呢? 謝謝各位
m8815010
版主


發表:99
回覆:372
積分:289
註冊:2003-11-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-02-25 09:50:27 IP:61.63.xxx.xxx 未訂閱
引言: 各位好: 我在Form上拉一個TEdit,把它原先的WndProc換成我自己的,想要攔下中文字的內碼,但是發現非常奇怪的現象。 部分的CODE的如下:
void __fastcall TForm1::MyEditWndProc(TMessage & Message)
{
   int lParam=Message.LParam;
   int wParam=Message.WParam;       switch(Message.Msg)
   {
      //case WM_IME_CHAR:
      case WM_CHAR:
      {
        //add code to process wParam
      }
      break;
   }        OldEditWndProc(Message);
} 
發現,在Form的Edit上打 "我" 這個中文字(內碼為0xA7DA) 我用SPY 攔到的Message依序為: WM_CHAR wParam=0xDA (Lead byte) WM_CHAR wParam=0xA7 (trail byte) 但是我在我自己的程式裡攔到的Message為: WM_CHAR wParam=0xA7 就沒了 怎麼會這樣呢? 問題在哪裡呢? 謝謝各位
Homi你好< >: 之前也發現過這個問題,但應不影響,也就不了了之了< >! 我所謂的不影響是因為用WM_IME_CHAR就可以攔到完整的byte code(double),在其Wparam中,我想你好像也有這樣攔吧! 要追其原因,還不容易,發現應是對整個 >,一些小小研究結果: class="code"> //------------window message hook區--------------// extern "C" __declspec(dllexport) LRESULT CALLBACK GetMsgProc(int nCode,WPARAM wParam,LPARAM lParam); extern "C" __declspec(dllexport) bool __stdcall SetWndMsgHook(HWND hwnd,HINSTANCE hInstance); extern "C" __declspec(dllexport) void __stdcall UnHookWndMsg(); //------------------------視窗訊息攔截--------------------------// //Set Hook function bool __stdcall SetWndMsgHook(HWND hwnd,HINSTANCE hInstance) { //hWnd=hwnd; DWORD ThrdId; DWORD PrssId=GetWindowThreadProcessId(hwnd,&ThrdId); hIdleHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)GetMsgProc,hInstance,PrssId); if (!MsgHook) return false; return true; } //Un Hook function void __stdcall UnHookWndMsg() { UnhookWindowsHookEx(MsgHook); } //Message procedure LRESULT CALLBACK GetMsgProc(int nCode,WPARAM wParam,LPARAM lParam) { if (nCode>=0) { if (nCode==HC_ACTION) { MSG *messg=(PMSG)lParam; if (messg->message==WM_CHAR) { //char classname[128]; //ZeroMemory(classname,128); //GetClassName(messg->hwnd,classname,128); ShowMessage(messg->wParam); } } return 0; } return CallNextHookEx(hIdleHook,nCode,wParam,lParam); } 以上的code需寫在dll中,有問題再研究了!
Zard
尊榮會員


發表:24
回覆:396
積分:539
註冊:2003-11-26

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-02-25 11:34:14 IP:210.243.xxx.xxx 未訂閱
根據我的觀察應該是VCL的原因.所以我把你的碼改成下面這樣, 在BCB5裡就可以抓到0xDA, 0xA7了.
void __fastcall TForm1::MyEditWndProc(TMessage & Message)
{
   int lParam=Message.LParam;
   int wParam=Message.WParam;       switch(Message.Msg)
   {
      //case WM_IME_CHAR:
      case WM_CHAR:
      {
        //add code to process wParam
        Memo1->Lines->Add(IntToHex(wParam, 4));
      }
      break;
      
      // 不讓WM_CHAR 經過VCL的Message Loop 
      default: OldEditWndProc(Message);
   }        //拿掉這裡 
    //OldEditWndProc(Message);
}
附帶一提, 若我直接用VC 寫(不用MFC, 完全手工打造)一個視窗程式, 攔WM_CHAR, 也是可以抓到0xDA, 0xA7 發表人 - zard 於 2005/02/25 11:45:03 發表人 - zard 於 2005/02/25 12:59:27
Homi
一般會員


發表:19
回覆:23
積分:8
註冊:2003-07-26

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-03-01 19:01:32 IP:220.141.xxx.xxx 未訂閱
您們好: 首先,先謝謝m8815010和zard兩位。 我用 >。 補充一下說明,"我"(內碼為
系統時間:2024-05-11 17:35:13
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!