Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

自绘控件怎么获取输入法输入的字符 #126

Open
korimas opened this issue May 12, 2022 · 12 comments
Open

自绘控件怎么获取输入法输入的字符 #126

korimas opened this issue May 12, 2022 · 12 comments

Comments

@korimas
Copy link

korimas commented May 12, 2022

我需要捕获用户的按键输入,我看有个OnKeyPress,但govcl里没找到

@korimas
Copy link
Author

korimas commented May 12, 2022

奇怪,搜不到,但代码里又看到了。。。
image

@korimas
Copy link
Author

korimas commented May 12, 2022

又重新看了下代码,貌似paintbox没有keypress事件

@korimas
Copy link
Author

korimas commented May 12, 2022

我看lazarus的Tpanel有Canvas,也有keypress事件,不过govcl貌似没有,作者有计划支持吗?

@korimas
Copy link
Author

korimas commented May 13, 2022

image

现在通过mainform的keypress event来获取用户键盘输入,但发现个致命问题,可能导致这个软件流产(算是个windows下的ssh远程终端模拟器吧,自己练手玩玩的),单个按键输入(ascii字符)可以捕获了,但无法获得输入法输入,用输入法输入中文就会像下面截图中那样,无法被软件获取。
image

不知道作者有没有解决办法。

@korimas korimas changed the title 怎么捕获按键事件 自绘控件怎么获取输入法输入的字符 May 13, 2022
@ying32
Copy link
Owner

ying32 commented May 15, 2022

TForm增加了OnUTF8KeyPress 事件,例子可以看basic的,这里面可以捕捉输入的中文。需要自己编译liblcl和暂时使用dev分支的代码。

@korimas
Copy link
Author

korimas commented May 16, 2022

感谢作者,我试一下。
这个软件想模仿xshell,要是能做成也打算开源(业余搞搞)。

开源不易,小小赞助了一笔~,不知道有没有微信交流群?

@ying32
Copy link
Owner

ying32 commented May 16, 2022

感谢赞助!没有微信交流群,懒得管理。

@korimas
Copy link
Author

korimas commented May 16, 2022

的确可以了,多谢!
image

还有个困惑,像之前那张图,输入中文的时候会有个绿色箭头的框,在正常的edit控件下是没有的,感觉是当前没有输入焦点,不知道有没有办法解决?
image

@korimas
Copy link
Author

korimas commented May 16, 2022

我查了下,貌似要自己对接输入法

应用程序可以通过 IMM 对接输入法。所用的 win32 的 API 重点是如下几个

ImmGetContext 获取输入法上下文,用于后续所有的其他函数调用
ImmAssociateContext 关联输入法和对应的窗口,让输入法了解在哪个窗口输入
ImmSetCompositionWindow 用来设置输入法的窗口的坐标,也是本文最重要的函数

@ying32
Copy link
Owner

ying32 commented May 16, 2022

这个我没搞过啊,所以我也不知道

@korimas
Copy link
Author

korimas commented May 16, 2022

那我研究下看看

@skyqvn
Copy link

skyqvn commented Feb 4, 2024

关于imm:

package main

import (
	"github.com/ying32/govcl/vcl/types"
	"syscall"
	"unsafe"
)

const (
	CFS_DEFAULT        = 0x0000
	CFS_RECT           = 0x0001
	CFS_POINT          = 0x0002
	CFS_FORCE_POSITION = 0x0020
	CFS_CANDIDATEPOS   = 0x0040
	CFS_EXCLUDE        = 0x0080
)

/*
typedef struct tagRECT {
	LONG left;
	LONG top;
	LONG right;
	LONG bottom;
} RECT,*PRECT,*NPRECT,*LPRECT;
*/
type RECT struct {
	Left, Top, Right, Bottom int32
}

/*
typedef struct tagPOINT {
	LONG x;
	LONG y;
} POINT,*PPOINT,*NPPOINT,*LPPOINT;
*/
type POINT struct {
	X, Y int32
}

/*
typedef struct tagCOMPOSITIONFORM {
	DWORD dwStyle;
	POINT ptCurrentPos;
	RECT rcArea;
} COMPOSITIONFORM,*PCOMPOSITIONFORM,*NPCOMPOSITIONFORM,*LPCOMPOSITIONFORM;
*/
type COMPOSITIONFORM struct {
	DwStyle      types.DWORD
	PtCurrentPos POINT
	RcArea       RECT
}

type HIMC = uintptr

type DWORD = uint32

type WINBOOL = uintptr

var ImmDLL = syscall.NewLazyDLL("imm32.dll")

var (
	_ImmGetOpenStatus        = ImmDLL.NewProc("ImmGetOpenStatus")
	_ImmGetContext           = ImmDLL.NewProc("ImmGetContext")
	_ImmSetOpenStatus        = ImmDLL.NewProc("ImmSetOpenStatus")
	_ImmSetCompositionWindow = ImmDLL.NewProc("ImmSetCompositionWindow")
	_ImmAssociateContext     = ImmDLL.NewProc("ImmAssociateContext")
	_ImmAssociateContextEx   = ImmDLL.NewProc("ImmAssociateContextEx")
)

func ImmGetOpenStatus(unnamedParam1 HIMC) bool {
	b, _, _ := _ImmGetOpenStatus.Call(unnamedParam1)
	return b == 1
}
func ImmGetContext(unnamedParam1 types.HWND) HIMC {
	h, _, _ := _ImmGetContext.Call(unnamedParam1)
	return h
}

func ToWINBOOL(b bool) WINBOOL {
	if b {
		return 1
	}
	return 0
}

func ToBool(wb WINBOOL) bool {
	return wb == 1
}

func ImmSetOpenStatus(unnamedParam1 HIMC, unnamedParam2 WINBOOL) WINBOOL {
	b, _, _ := _ImmSetOpenStatus.Call(unnamedParam1, unnamedParam2)
	return b
}

func ImmSetCompositionWindow(unnamedParam1 HIMC, lpCompForm *COMPOSITIONFORM) WINBOOL {
	b, _, _ := _ImmSetCompositionWindow.Call(unnamedParam1, uintptr(unsafe.Pointer(lpCompForm)))
	return b
}

func ImmAssociateContext(unnamedParam1 types.HWND, unnamedParam2 HIMC) HIMC {
	h, _, _ := _ImmAssociateContext.Call(unnamedParam1, unnamedParam2)
	return h
}

const (
	//仅将输入法上下文关联到指定窗口的子窗口。
	IACE_CHILDREN = 0x0001
	//还原窗口的默认输入法上下文。
	IACE_DEFAULT = 0x0010
	//不要将输入法上下文与不与任何输入法上下文关联的窗口相关联。
	IACE_IGNORENOCONTEXT = 0x0020
)

func ImmAssociateContextEx(unnamedParam1 types.HWND, unnamedParam2 HIMC, unnamedParam3 DWORD) WINBOOL {
	b, _, _ := _ImmAssociateContextEx.Call(unnamedParam1, unnamedParam2, uintptr(unnamedParam3))
	return b
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants