vuivui
发表于 2016-7-18 15:09:57
本帖最后由 vuivui 于 2016-7-18 15:34 编辑
$BkColor=0xC0DCC0
$gui1=GUICreate('', 400, 300)
$Label1 = GUICtrlCreateLabel('Label1', 10, 10, 380, 280, 0x800000)
GUICtrlSetBkColor(-1, $BkColor)
GUISetState()
GUICreate("", 98, 28, 150, 60, 0x80000000, 0x40, $gui1)
$Label2 = GUICtrlCreateLabel('Label2', -1, -1, 100, 30)
GUICtrlSetBkColor(-1, $BkColor)
GUISetState()
GUICreate("", 100, 30, 150, 120, 0x80000000, 0x40, $gui1)
GUISetBkColor($BkColor)
$Button1 = GUICtrlCreateButton('Button1', -1, -1, 100, 30)
GUISetState()
GUICreate("", 98, 28, 150, 180, 0x80000000, 0x40, $gui1)
$Checkbox1 = GUICtrlCreateCheckbox('Checkbox1', -1, -1, 100, 30)
GUICtrlSetBkColor(-1, $BkColor)
GUISetState()
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case -3
Exit
Case $Label1
MsgBox(0, 'Label1', 'CtrlID = ' & $nMsg)
Case $Label2
MsgBox(0, 'Label2', 'CtrlID = ' & $nMsg)
Case $Button1
MsgBox(0, 'Button1', 'CtrlID = ' & $nMsg)
Case $Checkbox1
MsgBox(0, 'Checkbox1', 'CtrlID = ' & $nMsg)
EndSwitch
WEnd其实也不是很麻烦
若控件很多,Label1就自己用api写吧,库函数也有的。
vuivui
发表于 2016-7-18 15:16:49
按照原理来说,控件是比普通窗口更复杂的窗口,用c语言来写,写个控件比普通窗口麻烦多了,加几个普通窗口,性能上不会有多大影响的。
vuivui
发表于 2016-7-18 15:30:37
呵呵,木子兄,不知你到底实现什么功能,其实不用写Label1也是可以的,我4楼的代码你测一下看返回的是什么消息代码,应该是gui1或gui2吧,你就把这个消息写成Label1要实现的功能就行了吧。
水木子
发表于 2016-7-18 15:33:08
回复 17# vuivui
这个方法我一开始是想过,但是总觉得很别扭,因为当你点击这些子窗口的时候,你会发现父窗口标题栏会丢失激活状态。
例如你点击 $Button1 的时候,你会发现整个窗口外边框都会跟着有反应,这样是不是很别扭呢?
水木子
发表于 2016-7-18 15:34:32
回复 16# vuivui
#include <Array.au3>
#include <WinAPI.au3>
#include <ScreenCapture.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
$hGui0 = GUICreate('', 400, 300)
$Label1 = GUICtrlCreateLabel('Label1', 10, 10, 380, 280, $WS_BORDER)
GUICtrlSetBkColor(-1, 0xC0DCC0)
$hLabel1 = GUICtrlGetHandle($Label1)
$hRgn1 = _WinAPI_CreateRectRgn(0, 0, 400, 300)
$Label2 = GUICtrlCreateLabel('Label2', 250, 50, 100, 30, 0x01 + 0x0200 + $WS_BORDER)
_SetCtrlRegion($hRgn1, $Label2)
$Button1 = GUICtrlCreateButton('Button1', 150, 120, 100, 30)
_SetCtrlRegion($hRgn1, $Button1)
$Checkbox1 = GUICtrlCreateCheckbox('Checkbox1', 150, 190, 100, 30)
_SetCtrlRegion($hRgn1, $Checkbox1)
_WinAPI_SetWindowRgn($hLabel1, $hRgn1)
$sText = GUICtrlCreateLabel('1', 150, 240, 100, 30, 0x01 + 0x0200)
GUICtrlSetFont(-1, 10, 400, 0, '微软雅黑')
GUICtrlSetBkColor(-1, 0xC0DCC0)
GUISetState()
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case -3
Exit
Case $Label1
GUICtrlSetData($sText, 'Label1')
Case $Label2
GUICtrlSetData($sText, 'Label2')
Case $Button1
GUICtrlSetData($sText, 'Button1')
Case $Checkbox1
GUICtrlSetData($sText, 'Checkbox1')
EndSwitch
WEnd
Func _SetCtrlRegion($hFullRgn, $iCtrlID)
Local $aCtrlPos, $hCtrlRgn
$aCtrlPos = ControlGetPos($hGui0, '', $iCtrlID)
If Not @error Then
$hCtrlRgn = _WinAPI_CreateRectRgn($aCtrlPos - 10, $aCtrlPos - 10, ($aCtrlPos + $aCtrlPos) - 10, ($aCtrlPos + $aCtrlPos) - 10)
_WinAPI_CombineRgn($hFullRgn, $hFullRgn, $hCtrlRgn, $RGN_XOR)
_WinAPI_DeleteObject($hCtrlRgn)
EndIf
EndFunc ;==>_SetCtrlRegion
这是另一种方法,不过这种方法也有弊端。
vuivui
发表于 2016-7-18 15:45:22
回复vuivui
这个方法我一开始是想过,但是总觉得很别扭,因为当你点击这些子窗口的时候,你会发现父窗 ...
水木子 发表于 2016-7-18 15:33 http://www.autoitx.com/images/common/back.gif
是这样的,焦点问题,多窗口是这样的,如感到别扭转移一下焦点就行了,这一点我感觉到没什么关系,反而有提示作用。
水木子
发表于 2016-7-18 15:53:25
回复 17# vuivui
回到1楼的代码,为什么给控件设置了置顶(Z 轴)属性。 GUICtrlSetState(-1, $GUI_ONTOP)
文本控件无法显示,按钮和复选框等控件则显示不正常。
但其实已经达到分层点击的效果了,只是显示有问题。要是能够解决这个问题就好了。
GUICtrlSetState(-1, $GUI_ONTOP) 对控件做了什么?
vuivui
发表于 2016-7-18 16:07:55
回复 22# 水木子
au3封装的函数,里面具体怎么运行是不知道的。我想在au3控件之间关系是并列的,叠放顺序会受到焦点转移、窗口激活的影响,所以要么自己写控件(窗口)可以掌控,要么就是用子窗口来建立从属关系。我们用窗口装控件实现,其实就是改变了控件的窗口属性。
vuivui
发表于 2016-7-18 16:16:09
回复 20# 水木子
绘制窗口显示区域思路很不错,圆角进度条什么的,经常要用到,如能提高融合度就更好了。
水木子
发表于 2016-7-18 16:59:42
回复 24# vuivui
刚刚又折腾了会儿,感觉这样效果更好些,更简单方便。#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
$hGui0 = GUICreate('', 400, 300)
$Label1 = GUICtrlCreateLabel('Label1', 10, 10, 380, 280, $WS_BORDER)
GUICtrlSetBkColor(-1, 0xC0DCC0)
$Label2 = GUICtrlCreateLabel('Label2', 150, 50, 100, 30, 0x01 + 0x0200 + $WS_BORDER)
;~ GUICtrlSetCursor(-1, 0)
$Button1 = GUICtrlCreateButton('Button1', 150, 120, 100, 30)
$Checkbox1 = GUICtrlCreateCheckbox('Checkbox1', 150, 190, 100, 30)
GUISetState()
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case -3
Exit
EndSwitch
WEnd
Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
Local $nID = BitAND($wParam, 0x0000FFFF) ; _WinAPI_LoWord 低位字
Local $nNotifyCode = BitShift($wParam, 16) ; _WinAPI_HiWord 高位字
$aCursorInfo = GUIGetCursorInfo($hGui0)
If Not @error Then
WinSetTitle($hGui0, '', 'CtrlID = ' & $aCursorInfo)
GUICtrlSetState ($aCursorInfo, $GUI_FOCUS)
Switch $aCursorInfo
Case $Label1
MsgBox(0, 'Label1', 'CtrlID = ' & $aCursorInfo)
Case $Label2
MsgBox(0, 'Label2', 'CtrlID = ' & $aCursorInfo)
Case $Button1
MsgBox(0, 'Button1', 'CtrlID = ' & $aCursorInfo)
Case $Checkbox1
If GUICtrlRead($Checkbox1) = 1 Then
GUICtrlSetState($Checkbox1, 4)
Else
GUICtrlSetState($Checkbox1, 1)
EndIf
EndSwitch
EndIf
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_COMMAND
vuivui
发表于 2016-7-18 17:42:02
本帖最后由 vuivui 于 2016-7-18 17:46 编辑
回复vuivui
刚刚又折腾了会儿,感觉这样效果更好些,更简单方便。
水木子 发表于 2016-7-18 16:59 http://www.autoitx.com/images/common/back.gif
很不错,我还以为跟一楼效果一样呢。处理了单击消息的响应,佩服钻研精神。
水木子
发表于 2016-7-18 17:47:10
回复 26# vuivui
复制你的代码执行,结果点击所有控件都返回 CtrlID = 3
vuivui
发表于 2016-7-18 17:54:08
呵呵,你动作真快,我已发现,你回复前改了,这应该是你最早发现这个问题才找解决办法的吧。
另外,WM_COMMAND函数有几行代码可以不要,Checkbox1改一下背景色是不是协调些。#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
$hGui0 = GUICreate('', 400, 300)
$Label1 = GUICtrlCreateLabel('Label1', 10, 10, 380, 280, $WS_BORDER)
GUICtrlSetBkColor(-1, 0xC0DCC0)
$Label2 = GUICtrlCreateLabel('Label2', 150, 50, 100, 30, 0x01 + 0x0200 + $WS_BORDER)
;~ GUICtrlSetCursor(-1, 0)
$Button1 = GUICtrlCreateButton('Button1', 150, 120, 100, 30)
$Checkbox1 = GUICtrlCreateCheckbox('Checkbox1', 150, 190, 100, 30)
GUICtrlSetBkColor(-1, 0xC0DCC0)
GUISetState()
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case -3
Exit
EndSwitch
WEnd
Func WM_COMMAND($hWnd, $Msg)
$aCursorInfo = GUIGetCursorInfo($hGui0)
If Not @error Then
WinSetTitle($hGui0, '', 'CtrlID = ' & $aCursorInfo)
GUICtrlSetState ($aCursorInfo, $GUI_FOCUS)
Switch $aCursorInfo
Case $Label1
MsgBox(0, 'Label1', 'CtrlID = ' & $aCursorInfo)
Case $Label2
MsgBox(0, 'Label2', 'CtrlID = ' & $aCursorInfo)
Case $Button1
MsgBox(0, 'Button1', 'CtrlID = ' & $aCursorInfo)
Case $Checkbox1
If GUICtrlRead($Checkbox1) = 1 Then
GUICtrlSetState($Checkbox1, 4)
Else
GUICtrlSetState($Checkbox1, 1)
EndIf
EndSwitch
EndIf
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_COMMAND
水木子
发表于 2016-7-18 18:06:23
回复 28# vuivui
嗯!这只是用来解决问题的例子,不用去纠结那些细节。
真正程序的代码老长了,我总不能全贴上来吧!
vuivui
发表于 2016-7-18 18:15:37
回复 29# 水木子
是的,核心是响应区域问题。我早前做过一个打字练习程序,用的是富文本实现的,碰到过类似的问题,都不知道是怎么解决的了,记得字根拆分提示用的是窗口与输入法的候选框跟随。