|
VFP 愛用者社區 本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
|
上一篇主題 :: 下一篇主題 |
發表人 |
內容 |
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用舊方法不行~傷腦筋....
感謝您的回答.. _________________ 大家好,請多指教 |
|
回頂端 |
|
|
|
|
您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章 您 無法 在這個版面編輯文章 您 無法 在這個版面刪除文章 您 無法 在這個版面進行投票 您 無法 在這個版面附加檔案 您 無法 在這個版面下載檔案
|
|