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# 水木子


    是的,核心是响应区域问题。我早前做过一个打字练习程序,用的是富文本实现的,碰到过类似的问题,都不知道是怎么解决的了,记得字根拆分提示用的是窗口与输入法的候选框跟随。
页: 1 [2] 3
查看完整版本: 【已解决】关于控件重叠且响应鼠标点击的问题讨论!