求教:TRadioGroup不单击时会触发OnClick事件

anhuishengshuchengxi 2017-11-21 08:00:18
现象是这样:
设置了TRadioGroup的OnClick事件,在单击改变选项时会触发,在单击不改变时不触发。另外在其他函数中改变TRadioGroup的ItemIndex时也会触发OnClick事件。

想要的效果是:
只有单击时触发此函数,这个单击不管有没有改变选项。

有这个事件吗?求指导,谢谢。
...全文
736 21 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
好的,谢谢指导,通用的确很重要。
ooolinux 2017-11-26
  • 打赏
  • 举报
回复
楼主如果想用TRadioGroup,可以查看一下TRadioGroup和TCustomRadioGroup的VCL源代码,说不定有办法。不过感觉依赖于VCL实现,不够通用(不是通过函数或方法)。
hongss 2017-11-25
  • 打赏
  • 举报
回复
ooolinux 2017-11-24
  • 打赏
  • 举报
回复
消息截获是这个意思,本来鼠标点击RadioGroup会选中一项,打个比方,总经理(操作系统)发消息(鼠标在客户区点击)给小王(RadioGroup),我这里简化了,实际上消息要从线程消息队列由消息循环获得以后分派,小王(RadioGroup)就会按照消息有相应的动作,但是部门经理提前把消息截获了,Handled=true; //该鼠标消息已处理 自己把消息处理了不再下发,小王(RadioGroup)根本没有收到消息,自己就不会有动作(这就是消息驱动),部门经理根据消息自己做了一些事,比如我代码中的:obj->Checked=true; //选中该选项 ,并且指挥下属做事,比如:RadioButton1Click(obj); //调用选项点击函数
ooolinux 2017-11-23
  • 打赏
  • 举报
回复
TRadioGroup的ClientRect应该是有的,你可以单独用代码测试一下。
ooolinux 2017-11-23
  • 打赏
  • 举报
回复
如果用RadioGroup,没办法用ControlAtPos这个方法了,我不知道有没有哪个方法可以获取RadioGroup内鼠标点击位置所在的是哪一个项目,手动写代码计算也许有可能,因为RadioGroup的Height、Items->Count都是可以得到,通过一些除法计算可以得到每一个项目的位置。
  • 打赏
  • 举报
回复
谢谢,单步调的时候就是发现point的值有问题,忽略了调用对象,修改后都能进入,这就回到了12#您所说的问题了。 我想简单了,以为单击后会修改ItemIndex,之后直接调用OnClick函数判断下就好了。 看样子是不行,谢谢指导。
ooolinux 2017-11-23
  • 打赏
  • 举报
回复
你可能ClientRect和BoundsRect都没分清楚, ClientRect是(0,0)—(x,y) BoundsRect是相对于窗体左上角而言的,就是(Left,Top)—(x+Left,y+Top) 使用哪个主要看对哪个控件或窗体调用ScreenToClient得到的鼠标坐标。 你用RadioGroup,如何判断鼠标点击的位置,是在原来选中的项目上,还是在其它项目上? 我那个代码: RadioButton1Click(obj); 这个 obj 已经代表是(指向)哪一个RadioButton了,就是鼠标位置所在的那个RadioButton,作为参数传给Sender: void __fastcall TForm1::RadioButton1Click(TObject *Sender) { TRadioButton *obj=(TRadioButton *)Sender; Memo1->Lines->Add(IntToStr(obj->Tag)+"."+obj->Caption); } 该函数中得到这个参数,能够区分是哪一个RadioButton。
  • 打赏
  • 举报
回复
谢谢指导,本来以为判断鼠标区域后直接调用OnClick函数,判断ItemIndex就行的,测试后: 调用的两个方法都无法判断区域; 直接调用OnClick函数,ItemIndex并没有修改为鼠标所在位置。 if(PtInRect(RadioGroup1->BoundsRect, point)) //鼠标在RadioGroup客户区内 { ………………测试后无法进入 Memo1->Lines->Add("PointOnClick bounds"); Handled = true; } if(PtInRect(RadioGroup1->ClientRect, point)) //鼠标在RadioGroup客户区内 { ………………测试后无法进入 将判断语句注释掉,直接进入,调用OnClick,发现ItemIndex没有变化 //获取鼠标位置所在的控件 RadioGroup1Click(RadioGroup1); //调用选项点击函数 Memo1->Lines->Add("PointOnClick client"); //int i = RadioGroup1->ItemIndex; //RadioGroup1->ItemIndex = i; Handled=true; //该鼠标消息已处理 }
ooolinux 2017-11-23
  • 打赏
  • 举报
回复
//几个RadioButton复用此事件处理函数 void __fastcall TForm1::RadioButton1Click(TObject *Sender) 这个代码里应该不必要。
  • 打赏
  • 举报
回复
谢谢,好多内容,好好学习下。 关于代码中, if(PtInRect(GroupBox1->ClientRect,point)) //鼠标在GroupBox客户区内 我想用于TRadioGroup,发现调用ClientRect或BoundsRect,都不行,可以解决吗? 实际应用中,一个个放RadioButton,如果数目多起来,没有RadioGroup方便哈……
ooolinux 2017-11-22
  • 打赏
  • 举报
回复
(TRadioButton *) 改成dynamic_cast<TRadioButton *>( )比较好。 简单点的方法看看别的前辈有没有。 如果对截获消息不熟悉,可以看看我的博客,转载了好几篇,应该比较完整了:http://blog.163.com/tab_98/ C++ Builder区 《C++ Builder高级应用开发指南》这本书也可以参考。
ooolinux 2017-11-22
  • 打赏
  • 举报
回复
截获消息也不算麻烦,我开始用中游的 void __fastcall TForm1::WndProc(TMessage &Message) 发现无法截获鼠标消息,改用上游的TApplication::OnMessage 事件处理函数可以截获,窗体上放一个TApplicationEvents组件就可以了, 主要代码(使用GroupBox里面放置单独的RadioButton,另外一个Memo1):
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
//几个RadioButton复用此事件处理函数
void __fastcall TForm1::RadioButton1Click(TObject *Sender)
{
    TRadioButton *obj=(TRadioButton *)Sender;
    Memo1->Lines->Add(IntToStr(obj->Tag)+"."+obj->Caption);    
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg,
      bool &Handled)
{
    if(Msg.message==WM_LBUTTONUP) //鼠标左键UP消息
    {
        TPoint point=GroupBox1->ScreenToClient(Msg.pt); //鼠标相对于GroupBox客户区坐标
        if(PtInRect(GroupBox1->ClientRect,point)) //鼠标在GroupBox客户区内
        {
            //获取鼠标位置所在的控件
            TRadioButton *obj=(TRadioButton *)GroupBox1->ControlAtPos(point,true,true);
            if(obj)
            {
                obj->OnClick=NULL;
                obj->Checked=true; //选中该选项
            //    obj->OnClick=RadioButton1Click;
                RadioButton1Click(obj); //调用选项点击函数
            }
            Handled=true; //该鼠标消息已处理
        }
    }
}
//---------------------------------------------------------------------------

  • 打赏
  • 举报
回复
在其他函数内修改属性: 是想避免触发OnClick事件,试过设为NULL,再恢复的方法,能够实现。 选中后再次单击: (报文通讯时,想重复发送该报文) 截获鼠标坐标就是麻烦了点,理论上是可以实现。 谢谢u010165006的解答,想等等看看有没有简单点的方法。
ooolinux 2017-11-22
  • 打赏
  • 举报
回复
如果用RadioGroup,替换它的WindowProc应该也可以。 不过截获消息以后,可能需要用代码来选中一个选项,如果用GroupBox加RadioButton的话,可以用ControlAtPos方法找到鼠标所在的子控件(某个RadioButton),把它Check。 如果用代码把Checked属性设置为true时不想触发OnClick,可以这样: RadioButton1->OnClick=NULL; RadioButton1->Checked=true; RadioButton1->OnClick=RadioButton1Click;
ooolinux 2017-11-22
  • 打赏
  • 举报
回复
1)在其他函数内使某个RadioButton的Checked属性值为true时,会触发OnClick函数。 —————— 这个是你要的,还是不要的?
ooolinux 2017-11-22
  • 打赏
  • 举报
回复
不知道你为什么要选中以后再次单击触发OnClick事件? 非要这么做应该也可以,麻烦一点,就是窗体截获鼠标事件消息,判断鼠标位置如果在RadioGroup1->BoundsRect内,调用RadioGroup1Click函数,否则,传递消息获得默认处理。
  • 打赏
  • 举报
回复
这样的效果和TRadioGroup貌似一样哎。 1)在其他函数内使某个RadioButton的Checked属性值为true时,会触发OnClick函数。 2)RadioButton被选中,再次单击,不会触发OnClick函数。
ooolinux 2017-11-21
  • 打赏
  • 举报
回复
如果用2楼这样做,只要设置一个RadioButton1的OnClick事件处理函数:
void __fastcall TForm1::RadioButton1Click(TObject *Sender)
{
    int tag;
    tag=((TRadioButton *)Sender)->Tag;
    switch(tag)
    {
    }
}
RadioButton2、RadioButton3等的OnClick都选为下拉的RadioButton1Click,就是复用RadioButton1Click事件处理函数, 几个RadioButton的Tag属性事先设置为不同的值就可以了。 Sender代表实际触发事件(比如点击事件)的那个控件。
ooolinux 2017-11-21
  • 打赏
  • 举报
回复
或者你用GroupBox里面放置单独的RadioButton来代替RadioGroup,后面多放一个没用的RadioButton,Checked属性设置为true,Visible属性设置为false。
加载更多回复(1)

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧