首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

一个最简单的16进制的计算器分析,该怎么处理

2012-05-20 
一个最简单的16进制的计算器分析HEXCALC程序可能是写程序偷懒的经典之作,如程序11-5所示。这个程序完全不呼

一个最简单的16进制的计算器分析
HEXCALC程序可能是写程序偷懒的经典之作,如程序11-5所示。这个程序完全不呼叫CreateWindow,也不处理WM_PAINT消息,不取得设备内容,也不处理鼠标消息。但是它只用了不到150行的原始码,就构成了一个具有完整键盘和鼠标接口以及10种运算的十六进制计算器。计算器如图11-5所示。
HEXCALC.C
   
   
  #include <windows.h>
  LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  PSTR szCmdLine, int iCmdShow)
  {
   
  static TCHAR szAppName[] = TEXT ("HexCalc") ;
  HWND hwnd ;
  MSG msg ;
  WNDCLASS wndclass ;
  wndclass.style = CS_HREDRAW | CS_VREDRAW;
  wndclass.lpfnWndProc = WndProc ;
  wndclass.cbClsExtra = 0 ;
  wndclass.cbWndExtra = DLGWINDOWEXTRA ; // Note!
   
  wndclass.hInstance = hInstance ;
  wndclass.hIcon = LoadIcon (hInstance, szAppName) ;
  wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
  wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1) ;
  wndclass.lpszMenuName = NULL ;
  wndclass.lpszClassName = szAppName ;
  if (!RegisterClass (&wndclass))
  {
  MessageBox ( NULL, TEXT ("This program requires Windows NT!"),
  szAppName, MB_ICONERROR) ;
  return 0 ;
  }
  hwnd = CreateDialog (hInstance, szAppName, 0, NULL) ;
  ShowWindow (hwnd, iCmdShow) ;
  while (GetMessage (&msg, NULL, 0, 0))
  {
  TranslateMessage (&msg) ;
  DispatchMessage (&msg) ; }
  return msg.wParam ;  
}
void ShowNumber (HWND hwnd, UINT iNumber)
  {
  TCHAR szBuffer[20] ;
  wsprintf (szBuffer, TEXT ("%X"), iNumber) ;
  SetDlgItemText (hwnd, VK_ESCAPE, szBuffer) ;
   
}
   

DWORD CalcIt (UINT iFirstNum, int iOperation, UINT iNum)
   
{
  switch (iOperation)
  {
  case '=': return iNum ;
  case '+': return iFirstNum + iNum ;
  case '-': return iFirstNum - iNum ;
  case '*': return iFirstNum * iNum ;
  case '&': return iFirstNum & iNum ;
  case '|': return iFirstNum | iNum ;
  case '^': return iFirstNum ^ iNum ;
  case '<': return iFirstNum << iNum ;
  case '>': return iFirstNum >> iNum ;
  case '/': return iNum ? iFirstNum / iNum: MAXDWORD ;
  case '%': return iNum ? iFirstNum % iNum: MAXDWORD ;
   
  default : return 0 ;
  }
  }
   

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
  {
   
  static BOOL bNewNumber = TRUE ;
  static int iOperation = '=' ;
  static UINT iNumber, iFirstNum ;
  HWND hButton ;
  switch (message)
  {
  case WM_KEYDOWN: // left arrow --> backspace


  if (wParam != VK_LEFT)
  break ;
  wParam = VK_BACK ;
  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 ;
  }
  case WM_COMMAND:
  SetFocus (hwnd) ;
  if (LOWORD (wParam) == VK_BACK)  
  ShowNumber (hwnd, iNumber /= 16) ; else if (LOWORD (wParam) == VK_ESCAPE)  
  ShowNumber (hwnd, iNumber = 0) ;
  else if (isxdigit (LOWORD (wParam)))  
  {
  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  
  {
  if (!bNewNumber)
  ShowNumber (hwnd, iNumber =
  CalcIt (iFirstNum, iOperation, iNumber)) ;
  bNewNumber = TRUE ;
  iOperation = LOWORD (wParam) ;
   
  }
   
  return 0 ;
   
  case WM_DESTROY:
   
  PostQuitMessage (0) ;
   
  return 0 ;
   
  }
   
  return DefWindowProc (hwnd, message, wParam, lParam) ;
   
}

这个问题实际就是一个16进制的计算器,我想问的是加入我们按下一个5,他就会显示一个5,但是这个代码让我理解不透,特别的if (iNumber <= MAXDWORD >> 4)
  ShowNumber (hwnd, iNumber = 16 * iNumber + wParam -
(isdigit (wParam) ? '0': 'A' - 10)) ;
  下面这个为什么还要减去10,减去10怎么会是对的呢,还有if (iNumber <= MAXDWORD >> 4)
可以判断最大只能是8位输出,他是怎么控制的,同行门帮我好好看看,也可以互相交流,我不会让你们白回答的,在下先在这里谢谢了


[解决办法]
再来解释下 为何if (iNumber <= MAXDWORD >> 4)?

MAXDWORD 即为0xFFFFFFFF右移四位则表示 除以16(这个你应该懂把)
所以当前大小必须要小于等于 "MAXDWORD >> 4"的值;
不然你刚输入一个16进制码,则iNumber会乘以16 再加上 这个16进制码 必然超过了 MAXDWORD了;
那也就是溢出了!

热点排行