Up_Down控件(SPIN)用法及Message解析

这年头搞纯C的人太少了,整个网上都是MFC,找个MSDN也没例子,到处都是写怎么用MFC的,干扰项啊。

首先,Up_Down的正确用法是依附在Edit上。依附(Set buddy)方法:
1.发送Message
SendMessage(GetDlgItem(hDlg, IDC_SPINA), UDM_SETBUDDY,(WPARAM)GetDlgItem(hDlg,IDC_EDITTYPE), 0);

2.在.rc中位于被依附对象的前一个,AutoBuddy为true。网络上说的TAB顺序的前一个,在属性窗口就没找到TAB顺序,直接开.rc文件,拖到EDIT后一个就成了。还要设置一个左靠齐或右靠齐。

然后就是Up_Down的用法了。Up_Down内部存储了一个NMUPDOWN struct,三个成员hdr,iDelta(按上则为负,按下则为正),iPos(当前位置)。

按下Up_Down后,控件向父窗口发送WM_NOTIFY消息,其中wParam为控件ID,lParam为一个指针。lParam指向NMHDR struct时,结构体的code成员标识了当前动作类型,Commctrl.h定义了很多,但实践中我发现只送出了UDN_DELTAPOS(-722)。我原来想象的Up_Down在按上和下时会产生不同的code,追踪了很久也没发现不同。原因是lParam指向NMUPDOWN struct时,结构体的iDelta成员和iPos成员标识出数值变化,设置了Buddy的EDIT后会把数值直接映射到EDIT,Up_Down的上下限,步长则用SendMessage调节。

但这样有一个问题,就是只支持整形数据,无法支持浮点数。刚开始我追踪Up_Down的pos变化。

               LRESULT lr = SendMessage(GetDlgItem(hDlg, IDC_SPIN2), UDM_GETPOS, 0, 0);

                if(HIWORD(lr) == 0)
                {
                    WORD pos = LOWORD(lr);

                    //Other stuff here
                    return TRUE;
                }

按照MSDN,lr的高位为0代表正常,非0出错,lr低位为pos值。实践中发现lr高位始终为1,pos在获取数据时始终要慢半拍,按了上,再按下,要过一次才能反映出来。我想这和消息机制有关,在WM_NOTIFY消息内部SendMessage,这个Message就排下一个队列了,所以就滞后了。

抛弃掉SendMessage的方法,我发现lParam指向NMUPDOWN struct后,无论iPos是低于下限还是高于上限,iDelta都能够正确反映出按键变化,Bingo!

    case WM_NOTIFY:
        switch (wParam)
        {
        case IDC_SPINA:
            NMHDR *lp = (NMHDR *)lParam;
            switch (lp->code)
            {
            case UDN_DELTAPOS:
                //UPDOWN原理:UPDOWN内置了一套加减机制,默认区间[0,100],与EDIT挂钩
                //此处抛弃UPDOWN内置计数,仅仅记录每次变化值,iDelta在上下界越界时依然可以反映出正确的1或-1
                if (((LPNMUPDOWN)lParam)->iDelta >=0)
                    a--;
                else
                    a++;
                UpdateToControl(hDlg);//自定
                CheckMech(hDlg, IDC_EDITTYPE, a, b, c, d);//自定
                break;
            }
            break;
        }
        return TRUE;

如此在iDelta判断中则可以对应上下按钮分别进行不同的操作了。

参考
Up-Down Control
https://msdn.microsoft.com/en-us/library/windows/desktop/bb759880(v=vs.85).aspx

Spin Control Position Issue (Windows)
http://stackoverflow.com/questions/13434945/spin-control-position-issue-windows

扫描二维码关注公众号,回复: 2292254 查看本文章

猜你喜欢

转载自blog.csdn.net/tomwillow/article/details/52709543