windows程序设计中的HEXCALC.c 程序的一些难点指导

windows程序设计中的HEXCALC.c程序是个比较让人费脑子的程序,现在将一些一般人看这个程序会遇到的问题说一下:

这些问题集中在下面一段代码中:

  case   WM_CHAR:
        if     ((wParam = (WPARAM) CharUpper ((TCHAR *) wParam)) == VK_RETURN)
        wParam = '=' ;
        if     (hButton = GetDlgItem (hwnd, wParam))
       {SendMessage (hButton, BM_SETSTATE, 1, 0) ;
        Sleep (100) ;
        SendMessage (hButton, BM_SETSTATE, 0, 0) ;
        }
        else
         {
        MessageBeep (0) ;
        break ;
         }
         // fall through
        case   WM_COMMAND:
        SetFocus (hwnd) ;
         if (LOWORD (wParam) == VK_BACK)                 //backspace
        ShowNumber (hwnd, iNumber /= 16) ;
        else if (LOWORD (wParam) == VK_ESCAPE)               // escape
        ShowNumber (hwnd, iNumber = 0) ;
        else if (isxdigit (LOWORD (wParam)))                 // hex digit
         { if (bNewNumber)
         {

 iFirstNum = iNumber ;

iNumber = 0 ;

        }
        bNewNumber = FALSE ;
         if     (iNumber <= MAXDWORD >> 4)
         ShowNumber (hwnd, iNumber = 16 * iNumber + wParam- (isdigit (wParam) ? '0': 'A' - 10)) ;
        else
        MessageBeep (0) ;
        }
       else    // operation
       {
      if (!bNewNumber)
         ShowNumber (hwnd, iNumber =CalcIt (iFirstNum, iOperation, iNumber)) ;

 iOperation = LOWORD (wParam) ;
        
                  }
        
                 return 0 ;

第一个问题: if     ((wParam = (WPARAM) CharUpper ((TCHAR *) wParam)) == VK_RETURN)
        wParam = '=' ;这个是把回车转化为等于号,问题是只是把wParam = '=',并没有再发一个wParam = '='的消息呀?

答:注意wParam = '=' ;之后并没有return 0或break之类的,所以wParam被改为 '='之后并没有完,还要继续往下走,所以无需再发一个wParam = '='的消息。

第二个问题: else if (isxdigit (LOWORD (wParam)))  中的isxdigit (LOWORD (wParam)),isxdigit 是检查一个数是否为十六制数,所以通过LOWORD (wParam)传回来的数总能转化为十六制进数,所以isxdigit (LOWORD (wParam))总为真,else if (isxdigit (LOWORD (wParam)))总能被执行,后面的那个else将永还会被执行

答:isxdigit 是检查一个数是否为十六制数字,不是检查一个数是否为十六制数,十六制数字为 16进制数:0123456789abcdefABCDEF,即一个数不管它是什么进制,只有转化为十六进制后与那些数字相同,isxdigit才会传回非零值。

第三个问题: if     (iNumber <= MAXDWORD >> 4)
         ShowNumber (hwnd, iNumber = 16 * iNumber + wParam- (isdigit (wParam) ? '0': 'A' - 10)) ;

MAXDWORD >> 4,MAXDWORD=0xFFFFFFFF;右移4位后为0xFFFFFFF,要iNumber <=0xFFFFFFF,是不是会使做运算的数位限制在28位,而不是32位。

答:这个问题纯属你计算错误,当iNumber达到了28位,即七个十六进制数字时,它仍然<= MAXDWORD >> 4,这时再进行后面的运算达到32位,即八个十六制进数字后,在做比较,就> MAXDWORD >> 4了,这时if     (iNumber <= MAXDWORD >> 4)就不成立了,此时iNumber正好达到了32位

第四个问题:  if (LOWORD (wParam) == VK_BACK)                 //backspace
        ShowNumber (hwnd, iNumber /= 16) ;
        else if (LOWORD (wParam) == VK_ESCAPE)               // escape
        ShowNumber (hwnd, iNumber = 0) ;

当按下第一个ESCAPE或BACK键时,iNumber的值并没有被初始化,这样调用了一个没有初始化的变量是否有问题?

答:iNumber被定义为static,凡是被定义为static的变量初始值为0,即使没有初始化,它的值也是0,而上面的代码在iNumber=0时完全可以。

第五个问题:当按下第一个数字按钮,iFirstNum = iNumber ;再接下往下按后面的数字按钮iNumber = 16 * iNumber + wParam -(isdigit (wParam) ? '0': 'A' - 10)),这时第一个被输入的数被分成了两次,第一个键按的数为存入了iFirstNum ,第一个键与后面的那个些共同形成的数被存入了iNumber ,当按下操作符键时,在没有键入新的操作数之前,上面的两个数就先操作了,这样岂不出问题?

答:不会出问题的,因为CalcIt (iFirstNum, iOperation, iNumber)) ;中iOperation初始值是'=',而   CalcIt (UINT iFirstNum, int iOperation, UINT iNum)函数在iOperation为'='时是 return iNum ,也就是说在进行输第二个数之前,虽然这个程序已经运行了一次 CalcIt 函数,但这次 CalcIt 函数并没有进行实际的运算,而只是把原来的数又返回了一遍。

第六个问题:当按下操作按钮后,第一次运行CalcIt 函数,但此时CalcIt 函数的iOperation变量并不是按下的操作按钮,而是'=',是不是不对呀?

答:很对呀,上面都说了,第一次运行CalcIt 函数时,第二个数都还没输入,此时的CalcIt 函数并没有作运算,只是将原来的数又返回去了,而且CalcIt 函数将iOperation的初始值变为你按下的运算按钮的值,此后在输完第二个数,再按下新的运算按钮,CalcIt 函数才会用头一次按下运算按钮的值进行上面的运算,并在运算完后把iOperation的值变成你按下的那个新的运算按钮的值。

第七个问题:ShowNumber (hwnd, iNumber = 16 * iNumber + wParam- (isdigit (wParam) ? '0': 'A' - 10)) ;中的wParam,为什么不是LOWORD (wParam),wParam的低16位是控件ID,也就是这个程序中按下数字按钮后形成的数,高16位是通知码,在很多资料上说控件产生的通知码是1呀,这么说来wParam与LOWORD (wParam)应该并不相等呀,因为wParam的高16位是1,LOWORD (wParam)没有高16位呀,也就是他的高16位可以说是0呀?

答:这个问题嘛,我也觉的有问题,可能是那些资料说的不对呀,反正我做了很多测试,结果发现在很多程序中按钮控件产生的WM_COMMAND消息的wParam,它的高16位确实是0,也就是说用按钮产生的消息中wParam和LOWORD (wParam)至少在这些程序中的值确实是相等的,只是位数不同。

第八个问题:ShowNumber (hwnd, iNumber = 16 * iNumber + wParam- (isdigit (wParam) ? '0': 'A' - 10)) ;,中如果wParam是阿拉伯数字的话,则iNumber = 16 * iNumber + wParam- 0;这好像不是按钮的标题上标的值吧,而是按钮的控件ID值,也就是那个标题上标的值的ASCii码表,这怎么能行呢?

答:你看清楚,减去的是'0',不是0,'0'是一个ASCii字符,他的值是48,所以比如按下了带1的按钮,它的ID值是49,减去'0'正好是1,后面的那个'A' - 10也差不多的情况,就不再介绍了。

好了,常见的那些问题都回答完毕,有不明白的可以问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值