找回密码
 加入
搜索
楼主: 水木子

[图形处理] 【已解决】关于控件重叠且响应鼠标点击的问题讨论!

  [复制链接]
发表于 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写吧,库函数也有的。

评分

参与人数 1金钱 +100 收起 理由
水木子 + 100 谢谢!辛苦了。

查看全部评分

发表于 2016-7-18 15:16:49 | 显示全部楼层
按照原理来说,控件是比普通窗口更复杂的窗口,用c语言来写,写个控件比普通窗口麻烦多了,加几个普通窗口,性能上不会有多大影响的。
发表于 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[0] - 10, $aCtrlPos[1] - 10, ($aCtrlPos[0] + $aCtrlPos[2]) - 10, ($aCtrlPos[1] + $aCtrlPos[3]) - 10)
                _WinAPI_CombineRgn($hFullRgn, $hFullRgn, $hCtrlRgn, $RGN_XOR)
                _WinAPI_DeleteObject($hCtrlRgn)
        EndIf
        
EndFunc   ;==>_SetCtrlRegion

这是另一种方法,不过这种方法也有弊端。
发表于 2016-7-18 15:45:22 | 显示全部楼层
回复  vuivui

这个方法我一开始是想过,但是总觉得很别扭,因为当你点击这些子窗口的时候,你会发现父窗 ...
水木子 发表于 2016-7-18 15:33



    是这样的,焦点问题,多窗口是这样的,如感到别扭转移一下焦点就行了,这一点我感觉到没什么关系,反而有提示作用。
 楼主| 发表于 2016-7-18 15:53:25 | 显示全部楼层
回复 17# vuivui

回到1楼的代码,为什么给控件设置了置顶(Z 轴)属性。 GUICtrlSetState(-1, $GUI_ONTOP)
文本控件无法显示,按钮和复选框等控件则显示不正常。
但其实已经达到分层点击的效果了,只是显示有问题。要是能够解决这个问题就好了。
GUICtrlSetState(-1, $GUI_ONTOP) 对控件做了什么?
发表于 2016-7-18 16:07:55 | 显示全部楼层
回复 22# 水木子


  au3封装的函数,里面具体怎么运行是不知道的。我想在au3控件之间关系是并列的,叠放顺序会受到焦点转移、窗口激活的影响,所以要么自己写控件(窗口)可以掌控,要么就是用子窗口来建立从属关系。我们用窗口装控件实现,其实就是改变了控件的窗口属性。
发表于 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[4])
                GUICtrlSetState ($aCursorInfo[4], $GUI_FOCUS)
                Switch $aCursorInfo[4]
                        Case $Label1
                                MsgBox(0, 'Label1', 'CtrlID = ' & $aCursorInfo[4])
                        Case $Label2
                                MsgBox(0, 'Label2', 'CtrlID = ' & $aCursorInfo[4])
                        Case $Button1
                                MsgBox(0, 'Button1', 'CtrlID = ' & $aCursorInfo[4])
                        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 17:42:02 | 显示全部楼层
本帖最后由 vuivui 于 2016-7-18 17:46 编辑
回复  vuivui

刚刚又折腾了会儿,感觉这样效果更好些,更简单方便。
水木子 发表于 2016-7-18 16:59


很不错,我还以为跟一楼效果一样呢。处理了单击消息的响应,佩服钻研精神。
 楼主| 发表于 2016-7-18 17:47:10 | 显示全部楼层
回复 26# vuivui

复制你的代码执行,结果点击所有控件都返回 CtrlID = 3
发表于 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[4])
                GUICtrlSetState ($aCursorInfo[4], $GUI_FOCUS)
                Switch $aCursorInfo[4]
                        Case $Label1
                                MsgBox(0, 'Label1', 'CtrlID = ' & $aCursorInfo[4])
                        Case $Label2
                                MsgBox(0, 'Label2', 'CtrlID = ' & $aCursorInfo[4])
                        Case $Button1
                                MsgBox(0, 'Button1', 'CtrlID = ' & $aCursorInfo[4])
                        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

嗯!这只是用来解决问题的例子,不用去纠结那些细节。
真正程序的代码老长了,我总不能全贴上来吧!
发表于 2016-7-18 18:15:37 | 显示全部楼层
回复 29# 水木子


    是的,核心是响应区域问题。我早前做过一个打字练习程序,用的是富文本实现的,碰到过类似的问题,都不知道是怎么解决的了,记得字根拆分提示用的是窗口与输入法的候选框跟随。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-19 11:52 , Processed in 0.080049 second(s), 16 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表