fenhanxue 发表于 2019-1-12 20:37:16

当通过代码改变combo内容的时候,如何同时触发GUICtrlSetOnEvent所对应的函数

本帖最后由 fenhanxue 于 2019-1-12 20:50 编辑

问题比较拗口。是这样的,我的一个程序,代码已经写好了,要添加一个小功能,原程序已有的代码太多了,不允许改动,因为一改动要改的地方就实在太多太多了。

下面是我的原程序的简化模型:#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <GuiComboBox.au3>
Opt("GUIOnEventMode", 1)

GUICreate("窗")

Local $n = 2;这里简化了模型,实际上n数字很大,例如 n= 100
Local $combo_array
For $i = 1 To $n
      $combo_array[$i] = GUICtrlCreateCombo('',150 * $i - 90 ,10,130,30)
      GUICtrlSetOnEvent($combo_array[$i], "udf");==>==>==>==>==>==>==>==>==>==>此行是问题的核心
Next
      
;对$combo_array赋值      注意,这里的字符都是无规律的,
GUICtrlSetData($combo_array,'随机字符1|随机字符2|随机字符3')
GUICtrlSetData($combo_array,'随机字符21|随机字符25|随机字符28')
      
;校验
$lable = GUICtrlCreateLabel('显示选择的结果',10,50,200,20)

GUISetOnEvent($GUI_EVENT_CLOSE, "QUIT")
GUISetState(@SW_SHOW)
While 1
      Sleep(10)
WEnd

Func udf();本部分的代码已经写好了,不允许改动               
      Local $temp = _GUICtrlComboBox_GetEditText(@GUI_CtrlId);      UDF里面,我是通过      @GUI_CtrlId      来判断到底哪个combo被点击了。
      GUICtrlSetData($lable,$temp)
EndFunc

Func QUIT()
    Exit
EndFunc   ;==>退出程序


原程序环境下,我用鼠标选任意个combo下的文字,udf() 都会做出对应的反应。
udf()本身代码不允许改动。主要是根据@GUI_CtrlId 这个参数来判断,到底鼠标点了哪一个combo的


我现在要增加的功能是,我按一下按钮,程序会用代码来勾选combo的指定选项。那么此时,如何去触发udf()呢?
也就是说:
例如,本来,我用鼠标点选第一个combo的第二个选项,那么udf()函数会做出相应,并显示‘随机字符2’
现在,我不想用鼠标点,而是用代码来选combo的第二个选项,那么如何让udf()被触发?
_GUICtrlComboBox_SetCurSel

也就是这样的代码,如何让他触发udf事件?下面的代码,并没有触发udf():
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <GuiComboBox.au3>
Opt("GUIOnEventMode", 1)

GUICreate("窗")

Local $n = 2;这里简化了模型,实际上n数字很大,例如 n= 100
Local $combo_array
For $i = 1 To $n
      $combo_array[$i] = GUICtrlCreateCombo('',150 * $i - 90 ,10,130,30)
      GUICtrlSetOnEvent($combo_array[$i], "udf");==>==>==>==>==>==>==>==>==>==>此行是问题的核心
Next
      
;对$combo_array赋值      注意,这里的字符都是无规律的,
GUICtrlSetData($combo_array,'随机字符1|随机字符2|随机字符3')
GUICtrlSetData($combo_array,'随机字符21|随机字符25|随机字符28')
      
;校验
$lable = GUICtrlCreateLabel('显示选择的结果',10,50,200,20)

$bt = GUICtrlCreateButton('按钮',10,100,200,40)
GUICtrlSetOnEvent($bt, "add");==>==>==>==>==>==>==>==>==>==>此行是问题的核心

GUISetOnEvent($GUI_EVENT_CLOSE, "QUIT")
GUISetState(@SW_SHOW)
While 1
      Sleep(10)
WEnd
Func add()
      _GUICtrlComboBox_SetCurSel($combo_array,1)
EndFunc

Func udf();本部分的代码已经写好了,不允许改动               
      Local $temp = _GUICtrlComboBox_GetEditText(@GUI_CtrlId);      UDF里面,我是通过      @GUI_CtrlId      来判断到底哪个combo被点击了。
      GUICtrlSetData($lable,$temp)
EndFunc

Func QUIT()
    Exit
EndFunc   ;==>退出程序

当然,这样的代码也并没达到我想要的目的:#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <GuiComboBox.au3>
Opt("GUIOnEventMode", 1)

GUICreate("窗")

Local $n = 2;这里简化了模型,实际上n数字很大,例如 n= 100
Local $combo_array
For $i = 1 To $n
      $combo_array[$i] = GUICtrlCreateCombo('',150 * $i - 90 ,10,130,30)
      GUICtrlSetOnEvent($combo_array[$i], "udf");==>==>==>==>==>==>==>==>==>==>此行是问题的核心
Next
      
;对$combo_array赋值      注意,这里的字符都是无规律的,
GUICtrlSetData($combo_array,'随机字符1|随机字符2|随机字符3')
GUICtrlSetData($combo_array,'随机字符21|随机字符25|随机字符28')
      
;校验
$lable = GUICtrlCreateLabel('显示选择的结果',10,50,200,20)

$bt = GUICtrlCreateButton('按钮',10,100,200,40)
GUICtrlSetOnEvent($bt, "add");==>==>==>==>==>==>==>==>==>==>此行是问题的核心

GUISetOnEvent($GUI_EVENT_CLOSE, "QUIT")
GUISetState(@SW_SHOW)
While 1
      Sleep(10)
WEnd
Func add()
      _GUICtrlComboBox_SetCurSel($combo_array,1)
      udf()
EndFunc

Func udf();本部分的代码已经写好了,不允许改动               
      Local $temp = _GUICtrlComboBox_GetEditText(@GUI_CtrlId);      UDF里面,我是通过      @GUI_CtrlId      来判断到底哪个combo被点击了。
      GUICtrlSetData($lable,$temp)
EndFunc

Func QUIT()
    Exit
EndFunc   ;==>退出程序
因为上面的代码,在执行 udf()的时候, @GUI_CtrlId实际上已经变成按钮的id了,而不是我原设想的combo的id。



也就是这样的代码,并不能达到和鼠标点击combo一模一样的效果: _GUICtrlComboBox_SetCurSel($combo_array,1)
        udf()


fenhanxue 发表于 2019-1-12 21:18:17

实际上再简化下问题可能就是如何改变   @GUI_CtrlId 这个参数的值?
也就是怎么把第一个combo的id赋值给   @GUI_CtrlId

chzj589 发表于 2019-1-13 17:54:23

fenhanxue 发表于 2019-1-12 21:18
实际上再简化下问题可能就是如何改变   @GUI_CtrlId 这个参数的值?
也就是怎么把第一个combo的id赋值给   ...

这样理解不知对不:

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <GuiComboBox.au3>
Opt("GUIOnEventMode", 1)

GUICreate("窗")

Local $n = 2;这里简化了模型,实际上n数字很大,例如 n= 100
Local $combo_array
For $i = 1 To $n
        $combo_array[$i] = GUICtrlCreateCombo('', 150 * $i - 90, 10, 130, 30)
        ;GUICtrlSetOnEvent($combo_array[$i], "udf");==>==>==>==>==>==>==>==>==>==>此行是问题的核心
        GUICtrlSetOnEvent($combo_array[$i], "add")
Next
;对$combo_array赋值      注意,这里的字符都是无规律的,
GUICtrlSetData($combo_array, '随机字符1|随机字符2|随机字符3')
GUICtrlSetData($combo_array, '随机字符21|随机字符25|随机字符26|随机字符28')
;校验
$lable = GUICtrlCreateLabel('显示选择的结果', 10, 50, 200, 20)
$bt = GUICtrlCreateButton('按钮', 10, 100, 200, 40)
GUICtrlSetOnEvent($bt, "add");==>==>==>==>==>==>==>==>==>==>此行是问题的核心
GUISetOnEvent($GUI_EVENT_CLOSE, "QUIT")
GUISetState(@SW_SHOW)
While 1
        Sleep(10)
WEnd
Func add()
        Local $comboa = @GUI_CtrlId - 2
        If $comboa = "1" Then;combo信息
                MsgBox(0, "GUI_CtrlId", $comboa)
                _GUICtrlComboBox_SetCurSel($combo_array, 0)
                udf()
        ElseIf $comboa = "2" Then;combo信息
                MsgBox(0, "GUI_CtrlId", $comboa)
                _GUICtrlComboBox_SetCurSel($combo_array, 1)
                udf1()
        EndIf
EndFunc   ;==>add

Func udf();本部分的代码已经写好了,不允许改动
        Local $temp = _GUICtrlComboBox_GetEditText(@GUI_CtrlId);      UDF里面,我是通过      @GUI_CtrlId      来判断到底哪个combo被点击了。
        GUICtrlSetData($lable, $temp)
EndFunc   ;==>udf
Func udf1();本部分的代码已经写好了,不允许改动
        Local $temp = _GUICtrlComboBox_GetEditText(@GUI_CtrlId);      UDF里面,我是通过      @GUI_CtrlId      来判断到底哪个combo被点击了。
        GUICtrlSetData($lable, $temp)
EndFunc   ;==>udf1
Func QUIT()
        Exit
EndFunc   ;==>QUIT

fenhanxue 发表于 2019-1-13 19:10:44

本帖最后由 fenhanxue 于 2019-1-13 19:20 编辑

chzj589 发表于 2019-1-13 17:54
这样理解不知对不:
实际的源程序,控件非常多,combo的id其实也没什么规律,这个方法行是行的,就是得把所有的控件的编号全部都找出来并列举一遍,例如我有100个combo,那工作量就非常大啦。

我现在想来想去,可能我要问的问题是这样的:
已知两个控件ID:$combo1和$bt1
求:
当鼠标点击 $bt1 后,如何让 @GUI_CtrlId等于 $combo1
我们都知道,鼠标点击 $bt1 后, @GUI_CtrlId 肯定是等于 $bt1的,那么用哪些代码,可以让 @GUI_CtrlId 等于 $combo1


ControlClick?
GUICtrlSendMsg ?


ControlClick好像不稳定,有时候会出现没有点上的情况

GUICtrlSendMsg这个不知道具体的写法

chzj589 发表于 2019-1-13 19:55:46

本帖最后由 chzj589 于 2019-1-14 09:40 编辑

fenhanxue 发表于 2019-1-13 19:10
实际的源程序,控件非常多,combo的id其实也没什么规律,这个方法行是行的,就是得把所有的控件的编号全 ...
不好意思。昨天晚上家里小孩在捣乱,没经过测试就帖上来。重发代码:

{:face (192):}

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <GuiComboBox.au3>
Opt("GUIOnEventMode", 1)
$Form1 = GUICreate("窗")
Local $n = 2;这里简化了模型,实际上n数字很大,例如 n= 100
Local $combo_array
;For $i = 1 To $n
;$combo_array[$i] = GUICtrlCreateCombo('', 150 * $i - 90, 10, 130, 30)
;GUICtrlSetOnEvent($combo_array[$i], "udf");==>==>==>==>==>==>==>==>==>==>此行是问题的核心
;GUICtrlSetOnEvent($combo_array[$i], "add")
;Next
$combo1 = GUICtrlCreateCombo('', 30, 10, 130, 30)
;GUICtrlSetOnEvent(-1, "_idCombo");"add")
$combo2 = GUICtrlCreateCombo('', 180, 10, 130, 30)
;GUICtrlSetOnEvent(-1, "_idCombo1");"add")
;对$combo_array赋值      注意,这里的字符都是无规律的,
GUICtrlSetData($combo1, '随机字符1|随机字符2|随机字符3')
GUICtrlSetData($combo2, '随机字符21|随机字符25|随机字符26|随机字符28')
ControlCommand($Form1, "", 'ComboBox1', "SetCurrentSelection", 0)
ControlCommand($Form1, "", 'ComboBox2', "SetCurrentSelection", 0)
$lable1 = GUICtrlCreateLabel('显示选择的结果', 30, 50, 20, 30)
$com1 = _GUICtrlComboBox_GetCurSel($combo1)
GUICtrlSetData($lable1, $com1)
$lable2 = GUICtrlCreateLabel('显示选择的结果', 180, 50, 20, 30)
$com2 = _GUICtrlComboBox_GetCurSel($combo2)
GUICtrlSetData($lable2, $com2)
$lablea2 = GUICtrlCreateLabel('', 220, 50, 20, 30)
$sComboRead = _GUICtrlComboBox_GetCount($combo2)
GUICtrlSetData($lablea2, $sComboRead)
;校验
$lable = GUICtrlCreateLabel('显示选择的结果', 10, 90, 200, 30)
$bt = GUICtrlCreateButton('按钮', 10, 150, 200, 40)
GUICtrlSetOnEvent($bt, "_idComboa");==>==>==>==>==>==>==>==>==>==>此行是问题的核心
GUISetOnEvent($GUI_EVENT_CLOSE, "QUIT")
GUISetState(@SW_SHOW)
While 1
      Sleep(10)
WEnd
Func _idComboa()
      ; 获取项目数
      ; MsgBox(0, "消息", "项目数量: " & _GUICtrlComboBox_GetCount($combo2))
      $sComboReada = _GUICtrlComboBox_GetCount($combo2)
      $sComboRead = GUICtrlRead($lable2)
      If $sComboRead = $sComboReada Then
                GUICtrlSetData($lable2, "")

      Else
                $t = GUICtrlRead($lable2) + 1
                GUICtrlSetData($lable2, $t)
                ControlCommand($Form1, "", 'ComboBox2', "SetCurrentSelection", $t)
                $temp = GUICtrlRead($combo2)
                GUICtrlSetData($lable, $temp)
                GUICtrlSetColor($lable, 0x009900); 背景色
                GUICtrlSetFont($lable, 10, 600, 0, "微软雅黑")
      EndIf
EndFunc   ;==>_idComboa
Func QUIT()
      Exit
EndFunc   ;==>QUIT


chzj589 发表于 2019-1-16 08:35:28

chzj589 发表于 2019-1-13 19:55
不好意思。昨天晚上家里小孩在捣乱,没经过测试就帖上来。重发代码:

折腾来折腾去,变成这个样子。但是却学习了上下按钮控件的使用。


 

gzh888666 发表于 2019-1-23 22:52:26

初始化一个函数=0保存状态,触发就=1循环了写个判断$if=1 执行

fenhanxue 发表于 2019-1-24 15:30:15

gzh888666 发表于 2019-1-23 22:52
初始化一个函数=0保存状态,触发就=1循环了写个判断$if=1 执行
也是个思路,就是感觉这样改代码的工作量也有点大。。。
我在想有没什么办法,直接改变 @GUI_CtrlId 为我指定的控件id,这样是最省力的

afan 发表于 2020-10-5 12:55:31

本帖最后由 afan 于 2020-10-5 12:59 编辑

本贴比较具有相关问题的代表性,且问题及代码描述简洁明了,不知LZ最后是否已解决?
个人感觉不必纠结于@GUI_CtrlId触发,以下是一个简单的解决方法
1,原 GUICtrlSetOnEvent($combo_array[$i], "udf") 中的 "udf" 改为 "udf0"
2,增加新函数 udf0 定义段
3,原udf函数添加一个可选参数 $id=@GUI_CtrlId,同时将函数内所有@GUI_CtrlId改为$id
4,add测试函数内调用 udf() 内添加一个参数
#include <GuiComboBox.au3>
Opt("GUIOnEventMode", 1)

GUICreate("窗")

Local $n = 2;这里简化了模型,实际上n数字很大,例如 n= 100
Local $combo_array
For $i = 1 To $n
      $combo_array[$i] = GUICtrlCreateCombo('', 150 * $i - 90, 10, 130, 30)
;~         GUICtrlSetOnEvent($combo_array[$i], "udf");==>==>==>==>==>==>==>==>==>==>此行是问题的核心
      GUICtrlSetOnEvent($combo_array[$i], "udf0");>>>>>>>>>>>>>> "udf" 改为 "udf0"
Next

;对$combo_array赋值      注意,这里的字符都是无规律的,
GUICtrlSetData($combo_array, '随机字符1|随机字符2|随机字符3')
GUICtrlSetData($combo_array, '随机字符21|随机字符25|随机字符28')

;校验
$lable = GUICtrlCreateLabel('显示选择的结果', 10, 50, 200, 20)

$bt = GUICtrlCreateButton('按钮', 10, 100, 200, 40)
GUICtrlSetOnEvent($bt, "add");==>==>==>==>==>==>==>==>==>==>此行是问题的核心

GUISetOnEvent(-3, "QUIT")
GUISetState(@SW_SHOW)
While 1
      Sleep(10)
WEnd
Func add()
      _GUICtrlComboBox_SetCurSel($combo_array, 1)
      udf($combo_array) ;>>>>>>>>>>>>>>添加一个参数
EndFunc   ;==>add
Func udf0()      ;>>>>>>>>>>>>>>增加新函数 udf0 定义段
      udf()
EndFunc   ;==>udf0
Func udf($id=@GUI_CtrlId);本部分的代码已经写好了,不允许改动 >>>>>>>>>>>>>>添加一个可选参数 $id=@GUI_CtrlId,同时将函数内所有@GUI_CtrlId改为$id
      Local $temp = _GUICtrlComboBox_GetEditText($id);      UDF里面,我是通过      @GUI_CtrlId      来判断到底哪个combo被点击了。
      GUICtrlSetData($lable, $temp)
EndFunc   ;==>udf

Func QUIT()
      Exit
EndFunc   ;==>QUIT

fenhanxue 发表于 2020-10-18 21:36:26

谢A大百忙中指点呀
页: [1]
查看完整版本: 当通过代码改变combo内容的时候,如何同时触发GUICtrlSetOnEvent所对应的函数