-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmovesnote.py
171 lines (141 loc) · 6.26 KB
/
movesnote.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
'''
Author: Paoger
Date: 2023-12-08 10:43:27
LastEditors: Paoger
LastEditTime: 2024-01-27 14:08:07
Description:
Copyright (c) 2023 by Paoger, All Rights Reserved.
'''
from kivy.logger import Logger
from kivy.utils import platform
if platform == "win":
#解决windows下中文输入的候选词显示begin
import ctypes
from ctypes import wintypes
import subprocess
# windows api 准备
# GlobalAlloc = ctypes.windll.kernel32.GlobalAlloc
# GlobalLock = ctypes.windll.kernel32.GlobalLock
GlobalFree = ctypes.windll.kernel32.GlobalFree
GlobalFree.argtypes = wintypes.HGLOBAL,
# GlobalUnlock = ctypes.windll.kernel32.GlobalUnlock
# GlobalSize = ctypes.windll.kernel32.GlobalSize
GlobalLock = ctypes.windll.kernel32.GlobalLock
GlobalLock.argtypes = wintypes.HGLOBAL,
GlobalLock.restype = wintypes.LPVOID
GlobalUnlock = ctypes.windll.kernel32.GlobalUnlock
GlobalUnlock.argtypes = wintypes.HGLOBAL,
GlobalUnlock.restype = wintypes.BOOL
GlobalAlloc = ctypes.windll.kernel32.GlobalAlloc
GlobalAlloc.argtypes = (wintypes.UINT, ctypes.c_size_t)
GlobalAlloc.restype = wintypes.HGLOBAL
GlobalSize = ctypes.windll.kernel32.GlobalSize
GlobalSize.argtypes = wintypes.HGLOBAL,
GlobalSize.restype = ctypes.c_size_t
GMEM_MOVEABLE = 0x0002
GMEM_ZEROINIT = 0x0040
GHND = 0x0042
class CANDIDATELIST(ctypes.Structure):
_fields_ = [
('dwSize', wintypes.DWORD),
('dwStyle', wintypes.DWORD),
('dwCount', wintypes.DWORD),
('dwSelection', wintypes.DWORD),
('dwPageStart', wintypes.DWORD),
('dwPageSize', wintypes.DWORD),
('dwOffset', ctypes.ARRAY(wintypes.DWORD, 9+1))
]
#解决windows下中文输入的候选词显示end
from kivymd.app import MDApp
from kivymd.uix.textfield import MDTextField
from kivy.properties import StringProperty
#招法注解类
class Movesnote(MDTextField):
#显示输入词候选的Widget id
imc_id = StringProperty('imc_id')
def on_imc_id(self, instance, imc_id):
self.imc_id = imc_id
#pf = platform.system()
#if pf == "Windows":
if platform == "win":
#绑定输入键盘事件
self.bind(text=self.ime_press)
def ime_press(self,*args):
#pf = platform.system()
#if pf == "Windows":
if platform == "win":
user32 = ctypes.WinDLL(name="user32")
imm32 = ctypes.WinDLL(name="imm32")
h_wnd = user32.GetForegroundWindow()
h_imc = imm32.ImmGetContext(h_wnd)
# imm32.ImmSetOpenStatus(h_imc, False)
# mem = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 30)
# pcontents = GlobalLock(mem)
size = imm32.ImmGetCandidateListW(h_imc, 0, None, 0)
buffer = ctypes.create_string_buffer(size)
ptxt = ctypes.cast(buffer,ctypes.POINTER(CANDIDATELIST))
imm32.ImmGetCandidateListW.argtypes = (wintypes.HGLOBAL, wintypes.DWORD, ctypes.POINTER(CANDIDATELIST), wintypes.DWORD)
imm32.ImmGetCandidateListW.restype = ctypes.c_size_t
imm32.ImmGetCandidateListW(h_imc, 0, ptxt, size)
a = [ptxt.contents.dwOffset[i] for i in range(ptxt.contents.dwPageSize+1)]
op = [str(ai+1)+':'+str (buffer[a[ai]:a[ai+1]], encoding = 'utf-16') for ai in range(len(a)-1)]
#print(f"{op=}")
#竖向候选
#self.root.ids.outl.text = "\n".join(op)
#op = ['好','号','好多']
#横向候选
my_string = ''
for item in op:
my_string += item.replace(' \x00','') + ' '
app = MDApp.get_running_app()
#app.root.ids.id_movesnote_input.text = my_string
app.root.ids['id_screenmain'].ids[f'{self.imc_id}'].text = my_string
imm32.ImmReleaseContext(h_wnd, h_imc)
else:
pass
def __init__(self, **kwargs):
super(Movesnote, self).__init__(**kwargs)
""" pf = platform.system()
if pf == "Windows":
#绑定输入键盘事件
self.bind(text=self.ime_press) """
""" def on_touch_dowwn(self,touch):
if self.collide_point(*touch.pos):
self.pressed = touch.pos
if touch.is_double_tap:
self.on_double_tap()
return True
return super().on_touch_down(touch)
def on_double_tap(self):
Logger.debug(f'X-Chess Movesnote: on_double_tap {self.readonly=}')
if self.readonly == True:
self.readonly = False """
def on_focus(self, instance_text_field, focus: bool) -> None:
ret = super().on_focus(instance_text_field, focus)
if focus == False:
#if platform == "android":#安卓中由于输入法会遮挡注解信息所以,需要编辑时放开编辑,否则只读
# self.readonly = True
#print('User defocused')
app = MDApp.get_running_app()
#招法树必须先有
if app.moves_tree.root != None:
#更新当前节点的注释
#MDList的最后一个item
id = app.root.ids['id_screenmoves'].ids.id_moveslist.children[0].id
if id != None:
node = app.moves_tree.get_node(id)
notelen = node.data['notelen']
#print(f"before note==>{node.data['note']}")
#print(f"before notelen==>{notelen}")
Logger.debug(f"X-Chess Movesnote:before note==>{node.data['note']}")
node.data['note'] = self.text
#print(f"after note==>{self.text=},{node.data['note']}")
#一顿骚操作
s = f"{len(self.text.encode('gbk')):x}" # 10==>a
#print(f"{len(self.text.encode('gbk'))=},{s=}")
s = f"{s:0>8}"#a==>0000000a
notelen = f'{s[6:8]}{s[4:6]}{s[2:4]}{s[0:2]}' #0000000a==>0a000000
node.data['notelen'] = notelen
#print(f"after notelen==>{notelen}")
Logger.debug(f"X-Chess Movesnote:after note==>{node.data['note']}")
return ret