VFP 愛用者社區 首頁 VFP 愛用者社區
本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入

中文轉注音 windows api 出問題

 
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區
上一篇主題 :: 下一篇主題  
發表人 內容
yang1032



註冊時間: 2004-06-19
文章: 58


第 1 樓

發表發表於: 星期二 七月 01, 2008 10:44 am    文章主題: 中文轉注音 windows api 出問題 引言回覆

最近從ktop看到中文轉注音,我想轉成vfp來用,但windows api
發生問題,詳細如下,請先輩告知
clear
DECLARE Integer ImmEscape IN imm32.dll as ImmEscapeA ;
Integer hkl , ;
Integer himc , ;
Integer un , ;
any @lpv

DECLARE Integer GetKeyboardLayoutList IN user32 ;
Integer nBuff , ;
Integer @lpList

declare lplist[20]
for i =1 to 20
lplist[i]=0
next
lplist =0
retVal = GetKeyboardLayoutList (24,@lpList)
messagebox("ret="+str(retVal ))
for i = 1 to 20
? lpList[i]
next
IME_ESC_IME_NAME=4102
For i = 1 To retVal - 1 && '遍歷各輸入法句柄
theName =space(256)
ret= ImmEscapeA(lpList[i],0,4102,@theName) && 取得輸入法名稱
* // iMaxkey = ImmEscape(lpList[i], 0, IME_ESC_IME_NAME,@theName) && 取得輸入法名稱
* if at("注音",theName) >0
*/ message("注音")
* endif
messagebox("ret="+str(ret)+theName) && 無法 取得輸入法名稱
next
回頂端
檢視會員個人資料 發送私人訊息
nelsonchuang



註冊時間: 2003-09-04
文章: 563
來自: 臺灣

第 2 樓

發表發表於: 星期二 七月 01, 2008 10:50 am    文章主題: 引言回覆

我記得很久以前,我在這裡還是紅狐有貼了一篇,用vfp轉出各個中文的字根或是注音
原作者是香港人,你找一下吧,我記得確實有這樣的文章存在

_________________
大家好,請多指教
回頂端
檢視會員個人資料 發送私人訊息
yang1032



註冊時間: 2004-06-19
文章: 58


第 3 樓

發表發表於: 星期三 七月 02, 2008 6:20 pm    文章主題: 引言回覆

謝謝 nelsonchuang 的指導
問題已解決,全文如下:
t_class_phon_test.prg
close data
clear
set proc to t_tran_class
*public aplist[9], iHandleCount ,szImeName,p1,p2,p3

mm=createobject("tran_phon")
? mm.get_phon("再理嗎",0)
* getcomp()
? mm.p1,mm.p2,mm.p3

t_tran_class.prg

Define Class tran_phon as custom OLEPublic
#define IME_ESC_IME_NAME 4102
#define GCL_REVERSECONVERSION 2
#define HEAP_ZERO_MEMORY 8
#define IME_ESC_MAX_KEY 16*16*16+5
dimension aplist[9]
iHandleCount=0
p1=""
p2=""
p3=""

func get_phon
lpara t_st,t_mode
DECLARE Integer ImmEscape IN imm32.dll as ImmEscapeA ;
Integer hkl , ;
Integer himc , ;
Integer un , ;
string @lpv

DECLARE Integer GetKeyboardLayoutList IN user32 ;
Integer nBuff , ;
string @lpList

DECLARE String HeapAlloc IN kernel32 ;
INTEGER hHeap, ;
INTEGER dwFlags, ;
INTEGER dwBytes

DECLARE Integer ImmGetConversionList IN imm32.dll As ImmGetConversionListA ;
Integer hkl , ;
Integer himc , ;
String lpsz , ;
string @lpCandidateList , ;
Integer dwBufLen , ;
Integer uFlag

if this.GetComp() =.f.
MessageBox( "請先要有注音輸入法選擇輸入法!" )
return
endif
if empty(t_st)
MessageBox( "請先輸入一些文字!" , "警告提示")
return
endif
ret_st = this.PhnoKey(t_st,t_mode) &&;this.P1; //注音首碼,this.P2; //對映鍵盤this.P3; //注音全碼
CLEAR DLLS
return ret_st
endfunc

*// 求得現有輸入法
func GetComp()
result =.f.
szImeName =space(256)
plist =repl(chr(0),96)
this.iHandleCount = GetKeyboardLayoutList(24, @pList)
k =1
for i = 1 to this.iHandleCount *4
this.aplist[k]= asc(substr(plist,i,1)) +asc(substr(plist,i+1,1))*256+asc(substr(plist,i+2,1))*256*256+asc(substr(plist,i+3,1)) *256*256*256
i=i+3
k =k+1
next

for i=1 to this.iHandleCount
szImeName =space(256)
ret=ImmEscapeA(this.aplist[i],0,IME_ESC_IME_NAME,@szImeName)
if ret >0
if szImeName ="注音"
result =.t.
endif
endif
next
return result
endfunc
*// 找出注音鍵盤對應碼
func PhnoKey
lpara t_St,t_mode
this.P1=""
this.P2=""
this.P3=""
r=len( t_St)
for k=1 to r
if (substr(t_st,k,1) >chr(128) ) &&{ // 中文字
ss=""
key_=substr(t_st,k,2)
S= this.ChineseComp(key_) && // 找出注音,一次傳一漢字
*// 去全型空白
i= len(S)
for j=1 to i step 2
if substr(S,j,2) # " "
ss = ss+substr(S,j,2)
endif
next
k=k+1
S=ss
i=len(ss)
if i > 1
this.P2 = this.P2+this.KeyBoard_In(substr(S,1,2)) && // 此為對應鍵盤英數字
this.P1= this.P1+ SubStr(ss,1,2) && // 此為注音首音
for jk=0 to int(i/2)
this.P3 = this.P3+this.KeyBoard_In(SubStr(S,jk*2+1,2))
next
endif
else
this.P2 =this.P2+ substr(t_str,k,1) && // 非中文字
endif
next
return this.P1
endfunc
*// 求得單一繁體漢字注音拼音
func ChineseComp
lpara Chinese_Str && (AnsiString Chinese_Str)
sFound=""
szImeName=space(256)
for i=1 to this.iHandleCount
if ImmEscapeA(this.aplist[i], 0, 4102, @szImeName) > 0
sFound = this.QueryCompStr(this.aplist[i], Chinese_Str)
endif
if szImeName="注音"
i = i+this.iHandleCount
endif
next
return sFound &&; // 傳回注音拼音
endfunc
*// 取得組字字根
func QueryCompStr
lpara hkb,sChinese &&( HKL hKB,AnsiString sChinese )
Result=""
iMaxKey = ImmEscapeA(hKB, 0, IME_ESC_MAX_KEY, NULL) &&IME_ESC_MAX_KEY
if iMaxKey <= 0
return Result
endif
*// 看看這個輸入法是否支援 Reverse Conversion 功能
*// 同時, 偵測需要多大的空間容納取得的資訊
*// comment: 下次修改時可以改成動態配置記憶體的方式
dwGCL = ImmGetConversionListA( ;
hKB, ;
0, ;
sChinese, ;
NULL, ; &&NULL
0, ;
GCL_REVERSECONVERSION) &&GCL_REVERSECONVERSION
if (dwGCL <= 0 ) && // 該輸入法不支援 Reverse Conversion 功能
return Result
endif
*// 取得組字字根資訊, dwGCL 的值必須以上次呼叫 ImmGetConversionList
*// 傳回值代入
LOCAL dwBuff(dwGCL+1) AS Byte
dwBuff(1) = 0 &&
tCandidate = CHR(0) + SPACE(dwGCL)
dwGCL = ImmGetConversionListA( ;
hKB, ;
0, ;
sChinese, ;
@tCandidate, ;
dwGCL, ;
GCL_REVERSECONVERSION) &&GCL_REVERSECONVERSION
FOR xci = 1 TO dwGCL + 1
dwBuff(xci) = ASC(SUBSTR(tCandidate,xci,1))
ENDFOR
icount = dwBuff(8+1)
nth =1
if dwGCL > 0
IF nth <= icount &&nth =1注音
iStart = dwBuff((24 + (nth - 1) * 4) + 1)
Result = SUBSTR(tCandidate,iStart+1,(iStart + iMaxkey * 2 + 1) - iStart)
endif
endif
return Result
endfunc

*// 注音對映鍵盤位置
func KeyBoard_In
lpara Str &&(AnsiString Str)
key=""
if asc(substr(str,1,1)) >=128
tt_n1 = asc(substr(str,2,1))
if tt_n1 >127
tt_n1 = (256 -tt_n1) * -1
endif
* messagebox(str+str(tt_n1))
do case
case tt_n1= 116 && ㄅ
key="1"
case tt_n1= 117 && ㄆ
key="Q"
case tt_n1= 118 && ㄇ
key="A"
case tt_n1= 119 && ㄈ
key="Z"
case tt_n1= 120 && ㄉ
key="2"
case tt_n1= 121 && ㄊ
key="W"
case tt_n1= 122 && ㄋ
key="S"
case tt_n1= 123 && ㄌ
key="X"
case tt_n1= 124 && ㄍ
key="E"
case tt_n1= 125 && ㄎ
key="D"
case tt_n1= 126 && ㄏ
key="C"
case tt_n1= -95 && ㄐ
key="R"
case tt_n1= -94 && ㄑ
key="F"
case tt_n1= -93 && ㄒ
key="V"
case tt_n1= -92 && ㄓ
key="5"
case tt_n1= -91 && ㄔ
key="T"
case tt_n1= -90 && ㄕ
key="G"
case tt_n1= -89 && ㄖ
key="B"
case tt_n1= -88 && ㄗ
key="Y"
case tt_n1= -87 && ㄘ
key="H"
case tt_n1= -86 && ㄙ
key="N"
case tt_n1= -72 && ㄧ
key="U"
case tt_n1= -71 && ㄨ
key="J"
case tt_n1= -70 && ㄩ
key="M"
case tt_n1= -85 && ㄚ
key="8"
case tt_n1= -84 && ㄛ
key="I"
case tt_n1= -83 && ㄜ
key="K"
case tt_n1= -82 && ㄝ
key=","
case tt_n1= -81 && ㄞ
key="9"
case tt_n1= -80 && ㄟ
key="O"
case tt_n1= -79 && ㄠ
key="L"
case tt_n1= -78 && ㄡ
key="."
case tt_n1= -77 && ㄢ
key="0"
case tt_n1= -76 && ㄣ
key="P"
case tt_n1= -75 && ㄤ
key=";"
case tt_n1= -74 && ㄥ
key="/"
case tt_n1= -73 && ㄦ
key="-"
case tt_n1= -65 && ˋ
key="4"
case tt_n1= -66 && ˇ
key="3"
case tt_n1= -67 && ˊ
key="6"
case tt_n1= -69 && ˙
key="7"
other
key=""
endcase
endif
return (key)
endfunc
ENDDEFINE
回頂端
檢視會員個人資料 發送私人訊息
nelsonchuang



註冊時間: 2003-09-04
文章: 563
來自: 臺灣

第 4 樓

發表發表於: 星期三 七月 09, 2008 8:13 pm    文章主題: 引言回覆

看了你的文章,我再找以前貼的資料,發覺找不到,想想,有可能是貼到
飛狐俱樂部那個大爛站了.
只好把以前自己改良過的程式直接貼出來,有用就參考吧,
因為很久沒除錯了,所以...有錯請見諒...


FUNC _CLR
DECLARE LONG ImmEscape IN "IMM32" LONG,LONG,long,STRING@
DECLARE LONG ImmGetConversionList IN "IMM32" LONG,LONG,STRING,STRING@,LONG,LONG
DECLARE LONG ImmGetImeMenuItems IN "IMM32" LONG,LONG,LONG,STRING@,STRING@,LONG
DECLARE LONG ImmGetDescription IN "IMM32" LONG,STRING@,LONG
DECLARE LONG ImmIsIME IN 'IMM32' LONG
DECLARE LONG GetKeyboardLayout IN "USER32" LONG
DECLARE INTEGER GetKeyboardLayoutName IN "USER32" STRING@
DECLARE LONG GetKeyboardLayoutList IN "USER32" LONG,STRING@
DECLARE LONG ImmSimulateHotKey IN "imm32" LONG,LONG
DECLARE LONG ImmSetOpenStatus IN "imm32" LONG,long
DECLARE LONG ImmGetDefaultIMEWnd IN "imm32" LONG
DECLARE INTEGER FindWindow IN Win32API STRING class_name, STRING window_title
DECLARE LONG ActivateKeyboardLayout IN USER32 LONG, INTEGER
Declare Long GetWindow in "USER32" Long,Long

RETURN
***************************************************************************
FUNC 輸入法
PARA L1,WD,MTH &&L1鍵盤輸入控制項,WD 中文字,MTH 第幾個拆字法
IF ISNULL(MTH)
MTH=1
ENDIF
MAX_KEY=4101
_VERR=2
*!* gh=ImmGetImeMenuItems(L1,2,)
NTH=1
輸入字=''
BUFR=SPACE(20)&&找出有幾個輸入法,20表長度,BUFR 提供電腦丟回資料
拚字=ImmEscape(L1,0,MAX_KEY,@BUFR) &&找出這種拚字最長幾碼,注音4碼
IF 拚字 =0
RETURN .F.
ENDIF
NX=''
支援= ImmGetConversionList(l1,0,wd,@NX,0,2)
IF 支援<=0
RETUR .F.
ENDIF
NX1=REPL(' ',支援)
支援=ImmGetConversionList(l1,0,wd,@NX1,支援,2)
輸入字=''
***************************************************
*展開傳回的ASCii碼
***************************************************
DIME DWBUFF(支援+1)
FOR I=1 TO 支援+1
DWBUFF(I)=ASC(SUBS(NX1,I,1))
ENDFOR
**************************************************
*取出有幾個字根的組合
**************************************************
ICOUNT= DWBUFF(9)
**************************************************
IF 支援>0 &&字串長度
IF MTH>ICOUNT
RETURN .F.
ENDIF
J=0
ISTART=DWBUFF((24+(MTH-1)*4+1)) &&第25碼位置註明了第1個注音位置在何處
輸入字=SUBS(NX1,ISTART+1,(ISTART+拚字*2+1)-ISTART)
ENDIF
RETURN 輸入字
*************************************************************************
FUNC 轉成中文 &&切換成輸入法!
PARA SND
&&PARA WHD,MSG,WHD2
&&WHD2=FindWindow(NULL,_SCREEN.CAPTION)
GCH1=FindWindow(NULL,_SCREEN.CAPTION)
WHD2 = GetWindow(GCH1, 5)
WHD=GetKeyboardLayout(0)
HOT_KEY1=112
=imeshow(SND)
nh= ImmIsIME(WHD)
IF nh=0
=ImmSimulateHotkey(WHD2,hot_key1) &&HOT_KEY1)
WHD=GETKEYBOARDLAYOUT(0)
ENDIF
RETURN WHD
***************************************************************
PROCEDURE IMESHOW
para pCALL
LOCAL IMELIST[10, 2]
LOCAL xci , iIme_Lay

IMELIST[1,1] = "Eng"
IMELIST[1,2] = 67699721
IMELIST[2,1] = "立頡"
IMELIST[2,2] = -534510588
IMELIST[3,1] = "倉頡"
IMELIST[3,2] = -536738812
IMELIST[4,1] = "速成"
IMELIST[4,2] = -536673276
IMELIST[5,1] = "五筆"
IMELIST[5,2] = -534576125
IMELIST[6,1] = "注音"
IMELIST[6,2] = -536804348
IMELIST[7,1] = "快碼"
IMELIST[7,2] = -5342772732
IMELIST[8,1] = "九方"
IMELIST[8,2] = -534445052
iIme_Lay = IMELIST[1,2]
pCALL = ALLTRIM(pCALL)
FOR xci = 2 TO 8
IF pCALL == IMELIST[xci,1]
iIme_Lay = IMELIST[xci,2] &&抓出輸入法的位置
EXIT
ENDIF
ENDFOR
ActivateKeyboardLayout(iIme_Lay, 0)
ENDPROC
*************************************************************************
FUNC 記下中文 &&切換成輸入法!
*!* BUFR=SPACE(20)&&找出有幾個輸入法,20表長度,BUFR 提供電腦丟回資料
GCH1=FindWindow(NULL,_SCREEN.CAPTION)
WHD2 = GetWindow(GCH1, 5)
LBU=256
LBEFR=SPACE(LBU)
LCN= ImmGetDescription(whd2,@LBEFR,LBU)
RETURN LBEFR
***************************************************************
***************************************************************

_________________
大家好,請多指教
回頂端
檢視會員個人資料 發送私人訊息
ufochen



註冊時間: 2003-09-17
文章: 165


第 5 樓

發表發表於: 星期三 二月 03, 2010 1:13 am    文章主題: 引言回覆

yang1032 寫到:
謝謝 nelsonchuang 的指導
問題已解決,全文如下:
t_class_phon_test.prg
close data
clear
set proc to t_tran_class
*public aplist[9], iHandleCount ,szImeName,p1,p2,p3

mm=createobject("tran_phon")
? mm.get_phon("再理嗎",0)
* getcomp()
? mm.p1,mm.p2,mm.p3

執行時會跑出 "請先要有注音輸入法選擇輸入法!" 錯誤訊息 ,
請問是哪裡錯了! 切換成注音輸入法再執行還是會出現一樣的錯誤訊息
回頂端
檢視會員個人資料 發送私人訊息
spfrk



註冊時間: 2004-11-08
文章: 161


第 6 樓

發表發表於: 星期三 二月 03, 2010 9:44 am    文章主題: 引言回覆

各位狐友所討論的輸入法都是在 IME API, WINDOWS 7 已全部改成 TSF(Text Service Framework), 因此這些
功能在 WINDOWS 7 都是不能用的.
回頂端
檢視會員個人資料 發送私人訊息
nelsonchuang



註冊時間: 2003-09-04
文章: 563
來自: 臺灣

第 7 樓

發表發表於: 星期三 二月 03, 2010 9:46 am    文章主題: 引言回覆

>>執行時會跑出 "請先要有注音輸入法選擇輸入法!" 錯誤訊息 ,
你有設定了輸入法[注音輸入法]成為你的切換選項之一嗎?
因為這樣的錯誤,我從未發生過~(你是在說我提供的,還是樓主提供的方式?)

_________________
大家好,請多指教
回頂端
檢視會員個人資料 發送私人訊息
ufochen



註冊時間: 2003-09-17
文章: 165


第 8 樓

發表發表於: 星期四 二月 04, 2010 8:17 am    文章主題: 引言回覆

nelsonchuang 寫到:
>>執行時會跑出 "請先要有注音輸入法選擇輸入法!" 錯誤訊息 ,
你有設定了輸入法[注音輸入法]成為你的切換選項之一嗎?
因為這樣的錯誤,我從未發生過~(你是在說我提供的,還是樓主提供的方式?)

sorry 沒有表達清楚 , 是樓主提供的程式碼 , 會出錯 !
回頂端
檢視會員個人資料 發送私人訊息
nelsonchuang



註冊時間: 2003-09-04
文章: 563
來自: 臺灣

第 9 樓

發表發表於: 星期日 四月 14, 2013 11:34 am    文章主題: 引言回覆

spfrk 寫到:
各位狐友所討論的輸入法都是在 IME API, WINDOWS 7 已全部改成 TSF(Text Service Framework), 因此這些
功能在 WINDOWS 7 都是不能用的.

能否借問一下spfrk,你是否有Tsf 這方面的資料可供大家參考,謝謝~

_________________
大家好,請多指教
回頂端
檢視會員個人資料 發送私人訊息
spfrk



註冊時間: 2004-11-08
文章: 161


第 10 樓

發表發表於: 星期日 四月 14, 2013 6:05 pm    文章主題: 引言回覆

在windows 8 我試過了, 只要使用手動切換過一次 中文輸入法,
那就可以由程式來控制了,看起來,這個問題在windows8 已經改善,
VFP 的程式在 WINDOWS8 跑起來比WINDOWS7還順,尤其是在
TEXT BOX 輸入框間的切換很順暢,游標也很明確.
回頂端
檢視會員個人資料 發送私人訊息
nelsonchuang



註冊時間: 2003-09-04
文章: 563
來自: 臺灣

第 11 樓

發表發表於: 星期一 四月 15, 2013 9:47 am    文章主題: 引言回覆

spfrk 寫到:
在windows 8 我試過了, 只要使用手動切換過一次 中文輸入法,
那就可以由程式來控制了,看起來,這個問題在windows8 已經改善,
VFP 的程式在 WINDOWS8 跑起來比WINDOWS7還順,尤其是在
TEXT BOX 輸入框間的切換很順暢,游標也很明確.

所以您的意思是....用以前的舊方法..也可行,還是...TSF才是window 7後版本的解決方案?

_________________
大家好,請多指教
回頂端
檢視會員個人資料 發送私人訊息
spfrk



註冊時間: 2004-11-08
文章: 161


第 12 樓

發表發表於: 星期二 四月 16, 2013 11:16 pm    文章主題: 引言回覆

是的, 目前我有3台電腦,各別為 XP, WIN7, WIN8,共用鍵盤滑鼠螢幕,可以隨時
切換,主要是用來測試 WIN8 的狀況,目前使用起來,看樣子WIN8 還滿好用的,
尤其是網頁處裡的速度超快的.
回頂端
檢視會員個人資料 發送私人訊息
nelsonchuang



註冊時間: 2003-09-04
文章: 563
來自: 臺灣

第 13 樓

發表發表於: 星期三 四月 17, 2013 9:46 am    文章主題: 引言回覆

哦,原來win8又可以走回頭了用舊方法了,=.=||
我試了windows 7用舊方法不行~傷腦筋....
感謝您的回答..

_________________
大家好,請多指教
回頂端
檢視會員個人資料 發送私人訊息
從之前的文章開始顯示:   
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區 所有的時間均為 台北時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
無法 在這個版面附加檔案
無法 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作