谁能说一下MFC中backspace键的功能是怎么实现的?

等待一场救赎 2013-01-21 03:36:05
谁能说一下MFC中backspace键的功能是怎么实现的?最好有代码?
...全文
318 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
defu-lee 2013-01-21
  • 打赏
  • 举报
回复
先把原先的输出覆盖掉,再用新的输出代替,视觉上相当于回退了。比如:第一次用黑色的pen输出:"hello word" 想实现回退效果的话就要把上次的输出覆盖掉,比如用白色的pen再输出一次“hello word”,然后再用黑色pen输出“hello wor”。这样在视觉上就就像是被回退了。
向立天 2013-01-21
  • 打赏
  • 举报
回复
你什么意思? 什么叫怎么实现 你想知道键盘消息怎么实现?
jimette 2013-01-21
  • 打赏
  • 举报
回复
孙鑫的vc视频里面有!
孤客天涯 2013-01-21
  • 打赏
  • 举报
回复
keybd_event(VK_BACK,0, KEYEVENTF_EXTENDEDKEY | 0,0);
等待一场救赎 2013-01-21
  • 打赏
  • 举报
回复
等了半天没人来说说吗?
MFC计算器课程设计报告 地信091 指导老师: 2010.11.15 一.题目:利用MFC框架编写简易计算器 要求使用MFC框架在Visual Studio 6.0环境下编写一个简易的计算器,支持任意位数的加减乘数,正负转换,并且实现BackSpace CE C功能。 二.设计过程 1. Windows消息处理机制的理解 首先编写程序需要对Windows程序的消息处理机制(Message Handle)有个比较清晰的了解。Windows的程序都是通过消息来传送数据,有不需要用户参与的系统消息,比如异常处理等。还有用户消息,比如鼠标的单击,双击,盘的入等。 2. 界面的设计 仿照Windows附件里面的计算器,在资源视图画好界面,如图: 主要使用到Layout菜单的Align功能对各个按钮进行对其,使界面更加整洁。拖出的控件有上面的一个Edit控件用于显示数字,Button控件用于处理鼠标的消息。 3. 建立的变量,控件的命名,对应的消息处理函数对应表 ID CAPTION Message Handler IDD_CALC_DIALOG 简易计算器 1.0 Beta1版 N/A IDC_NUM0 0 OnNum0 IDC_NUM1 1 OnNum1 IDC_NUM2 2 OnNum2 IDC_NUM3 3 OnNum3 IDC_NUM4 4 OnNum4 IDC_NUM5 5 OnNum5 IDC_NUM6 6 OnNum6 IDC_NUM7 7 OnNum7 IDC_NUM8 8 OnNum8 IDC_NUM9 9 OnNum9 IDC_NEG +/- OnNeg IDC_PT . OnPt IDC_DIV / OnDiv IDC_MUL * OnMul IDC_MIN - OnMin IDC_ADD + OnAdd IDC_BACKSPACE BACK OnBackspace IDC_CE CE OnCe IDC_CLEAR C OnClear IDC_EQU = OnEqu IDC_DIS N/A N/A OnCal(double num) 变量定义: double poz; //保存小数点的位置,初始化为1,表示poz-1个小数点。 double m_Dis; //Edit控件上需要显示的数字 BOOL point_flag; //小数点表示位,判定是否是小数,是小数为1,不是小数为0。 double numfirst; //保存计算过程的前一个数字, double numsecond;//保存计算过程的第二个数字 char op;//记录当前的计算符号,可以为’+’,’-’,’*’,’/’,’=’,’c’,’n’ 变量初始化: poz=1; m_Dis = 0.0; numfirst=0; numsecond=0; op=0; 4. 设计思路 a) 首先考虑对所有按分为两类,数字类和符号类,0,1,2,3,4,5,6,7,8,9为数字类,+,-,*,/,=为符号类。数字在计算的过程最多需要保存两个,所以定义了两个double型变量numfirst和numsecond来进行存储。符号需要一个char op来存储。 b) 然后考虑在计算的过程,numfirst和numsecond的存储状态有三种,一种是numfirst==0 && numsecond==0 也就是程序刚开始运行还没有开始录入数字的状态。二种是numfirst!=0 && numsecond==0 也就是第一个数字已经录入,符号也已经录入时候把m_Dis的值直接赋值给numfirst,第三种是numfirst!=0 &&numsecond!=0,表示可以通过op来把两数合并为一个数。 c) 考虑到该计算器支持连续的计算,比如3.33+1.33*88/96= ?。所以必须在点符号Button也要计算出之前的结果,通过判断op,来计算,把两个数字合并为一个数字,方便下一次运算,功能近似于点=,所以把=也划分到符号类。 d) 因为数字全部使用的是double,入的数字必须通过一定的处理达到累加的效果,加上小数和整数的处理差异性大,所以分别用point_flag来判断,分别出来小数和整数。 5. 成员函数及其释义 因为对OnNum0()到OnNum9()的处理函数差异仅在一个数字上,可以通过调用一个共同的函数OnCal(double num)来简化源代码长度,增加模块性。 void CCalcDlg::OnCal(double num) { //分三种状态来处理 if(numfirst!=0 && numsecond!=0) { if(point_flag==TRUE) //判定为小数 { poz*=0.1; //小数进位 m_Dis=m_Dis+poz*num;//递增 UpdateData(false); //把结果从内存传递到屏幕 } else { m_Dis=m_Dis*10+num; UpdateData(false); } } if(numfirst!=0 && numsecond==0) { if(point_flag==TRUE) { poz*=0.1; m_Dis=m_Dis+poz*num; UpdateData(false); } else//判定为整数 { m_Dis=m_Dis*10+num;//递增 UpdateData(false); } } if(numfirst==0 && numsecond==0) { if(point_flag==TRUE) { poz*=0.1; m_Dis=m_Dis+poz*num; UpdateData(false); } else { m_Dis=m_Dis*10+num; UpdateData(false); } } } 以OnAdd()为例子讲解符号的处理函数,函数的功能是先判定之前按下字符时op的值,更具op的值来进行相应的运算。 void CCalcDlg::OnAdd() { //根据numfirst和numsecond和op的值分为5种状态。 if(numfirst!=0 && numsecond==0&&op=='+') { numsecond=m_Dis; numfirst=numfirst+numsecond; //之前按的是加把两个数赋值到前一个数 m_Dis=numfirst;//赋值给屏幕 numsecond=0; //从新赋值为0,清空,不影响下一次判断 UpdateData(FALSE); m_Dis=0; //屏幕的值同时清空 } if(numfirst!=0 && numsecond==0&&op=='-') { numsecond=m_Dis; numfirst=numfirst-numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst!=0 && numsecond==0&&op=='*') { numsecond=m_Dis; numfirst=numfirst*numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst!=0 && numsecond==0&&op=='/') { numsecond=m_Dis; numfirst=numfirst/numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst==0 && numsecond==0) { //该状态为程序启动还没有开始录入输入的状态 numfirst=m_Dis; //屏幕的值赋值到numfirst UpdateData(FALSE); m_Dis=0; } op='+'; //最后记录最后一个操作是+ poz=1;//小数点位置归位 point_flag=FALSE;//默认小数点标志为整数,也就是0,也就是FALSE } “+/-“按钮的处理函数 void CCalcDlg::OnNeg() { m_Dis=-m_Dis;//换个符号,其他都一样 UpdateData(FALSE); poz=1; point_flag=FALSE; } ‘.’按钮的处理函数 void CCalcDlg::OnPt() { point_flag=TRUE; //把标志位改为“小数点”状态 } “Backspace”按钮的处理 void CCalcDlg::OnBackspace() { //主要通过_gcvt()和strtod()函数进行字符串和浮点数之间的转换 char buffer[30]; //定义个装字符的数组 _gcvt(m_Dis,sizeof(m_Dis),buffer); //把m_Dis存的数字转换为string for(int i=0;i<30;i++) { if(buffer[i]=='.'&& buffer[i+1]==0)//判断是否为整数 { point_flag=FALSE; //标志位设置为“整数位” break; } } if(point_flag==TRUE) //如果是小数 { for(int j=0;jmessage,pMsg->wParam,pMsg->lParam); return CDialog::PreTranslateMessage(pMsg); } // CalculatorDlg.cpp : implementation file // #include "stdafx.h" #include "Calculator.h" #include "CalculatorDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CCalculatorDlg dialog CCalculatorDlg::CCalculatorDlg(CWnd* pParent /*=NULL*/) : CDialog(CCalculatorDlg::IDD, pParent) { //{{AFX_DATA_INIT(CCalculatorDlg) poz=1; numfirst=0; numsecond=0; op=0; m_Dis = 0.0; // num=0; //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CCalculatorDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CCalculatorDlg) DDX_Text(pDX, IDC_EDIT, m_Dis); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CCalculatorDlg, CDialog) //{{AFX_MSG_MAP(CCalculatorDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_NUM0, OnNum0) ON_BN_CLICKED(IDC_NUM1, OnNum1) ON_BN_CLICKED(IDC_NUM2, OnNum2) ON_BN_CLICKED(IDC_NUM3, OnNum3) ON_BN_CLICKED(IDC_NUM4, OnNum4) ON_BN_CLICKED(IDC_NUM5, OnNum5) ON_BN_CLICKED(IDC_NUM6, OnNum6) ON_BN_CLICKED(IDC_NUM7, OnNum7) ON_BN_CLICKED(IDC_NUM8, OnNum8) ON_BN_CLICKED(IDC_NUM9, OnNum9) ON_BN_CLICKED(IDC_ADD, OnAdd) ON_BN_CLICKED(IDC_NEG, OnNeg) ON_BN_CLICKED(IDC_PT, OnPt) ON_BN_CLICKED(IDC_BACKSPACE, OnBackspace) ON_BN_CLICKED(IDC_CE, OnCe) ON_BN_CLICKED(IDC_CLEAR, OnClear) ON_BN_CLICKED(IDC_MIN, OnMin) ON_BN_CLICKED(IDC_MUL, OnMul) ON_BN_CLICKED(IDC_DIV, OnDiv) ON_BN_CLICKED(IDC_EOU, OnEou) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CCalculatorDlg message handlers BOOL CCalculatorDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control } void CCalculatorDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CCalculatorDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CCalculatorDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CCalculatorDlg::OnCal(double num) {//分三种状态来处理 if(numfirst!=0 && numsecond!=0) { if(point_flag==TRUE) //判定为小数 { poz*=0.1; //小数进位 m_Dis=m_Dis+poz*num;//递增 UpdateData(false); //把结果从内存传递到屏幕 } else { m_Dis=m_Dis*10+num; UpdateData(false); } } if(numfirst!=0 && numsecond==0) { if(point_flag==TRUE) { poz*=0.1; m_Dis=m_Dis+poz*num; UpdateData(false); } else//判定为整数 { m_Dis=m_Dis*10+num;//递增 UpdateData(false); } } if(numfirst==0 && numsecond==0) { if(point_flag==TRUE) { poz*=0.1; m_Dis=m_Dis+poz*num; UpdateData(false); } else { m_Dis=m_Dis*10+num; UpdateData(false); } } } void CCalculatorDlg::OnNum0() { // TODO: Add your control notification handler code here OnCal(0); } void CCalculatorDlg::OnNum1() { // TODO: Add your control notification handler code here OnCal(1); } void CCalculatorDlg::OnNum2() { // TODO: Add your control notification handler code here OnCal(2); } void CCalculatorDlg::OnNum3() { // TODO: Add your control notification handler code here OnCal(3); } void CCalculatorDlg::OnNum4() { // TODO: Add your control notification handler code here OnCal(4); } void CCalculatorDlg::OnNum5() { // TODO: Add your control notification handler code here OnCal(5); } void CCalculatorDlg::OnNum6() { // TODO: Add your control notification handler code here OnCal(6); } void CCalculatorDlg::OnNum7() { // TODO: Add your control notification handler code here OnCal(7); } void CCalculatorDlg::OnNum8() { // TODO: Add your control notification handler code here OnCal(8); } void CCalculatorDlg::OnNum9() { // TODO: Add your control notification handler code here OnCal(9); } void CCalculatorDlg::OnAdd() { // TODO: Add your control notification handler code here { //根据numfirst和numsecond和op的值分为5种状态。 if(numfirst!=0 && numsecond==0&&op=='+') { numsecond=m_Dis; numfirst=numfirst+numsecond; //之前按的是加把两个数赋值到前一个数 m_Dis=numfirst;//赋值给屏幕 numsecond=0; //从新赋值为0,清空,不影响下一次判断 UpdateData(FALSE); m_Dis=0; //屏幕的值同时清空 } if(numfirst!=0 && numsecond==0&&op=='-') { numsecond=m_Dis; numfirst=numfirst-numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst!=0 && numsecond==0&&op=='*') { numsecond=m_Dis; numfirst=numfirst*numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst!=0 && numsecond==0&&op=='/') { numsecond=m_Dis; numfirst=numfirst/numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst==0 && numsecond==0) { //该状态为程序启动还没有开始录入输入的状态 numfirst=m_Dis; //屏幕的值赋值到numfirst UpdateData(FALSE); m_Dis=0; } op='+'; //最后记录最后一个操作是+ poz=1;//小数点位置归位 point_flag=FALSE;//默认小数点标志为整数,也就是0,也就是FALSE } } void CCalculatorDlg::OnNeg() { // TODO: Add your control notification handler code here m_Dis=-m_Dis;//换个符号,其他都一样 UpdateData(FALSE); poz=1; point_flag=FALSE; } void CCalculatorDlg::OnPt() { // TODO: Add your control notification handler code here point_flag=TRUE; //把标志位改为"小数点"状态 } void CCalculatorDlg::OnBackspace() { // TODO: Add your control notification handler code here //主要通过_gcvt()和strtod()函数进行字符串和浮点数之间的转换 char buffer[30]; //定义个装字符的数组 _gcvt(m_Dis,sizeof(m_Dis),buffer); //把m_Dis存的数字转换为string for(int i=0;i<30;i++) { if(buffer[i]=='.'&& buffer[i+1]==0)//判断是否为整数 { point_flag=FALSE; //标志位设置为"整数位" break; } } if(point_flag==TRUE) //如果是小数 { for(int j=0;j<30;j++) { if(buffer[j]==0) { buffer[j-1]=0; //把'\0'之前的字符赋值为'\0',就相当于剪掉最后一位 break; } } } else //如果是整数 { buffer[i-1]=0; //剪掉'.'之前那位 } m_Dis=strtod(buffer,NULL);//再用strtod弄成浮点数 UpdateData(FALSE); poz=1; } void CCalculatorDlg::OnCe() { // TODO: Add your control notification handler code here if(numfirst!=0 && numsecond==0)//CE只能修改第二个数字 { m_Dis=0; //把屏幕的值赋值为0 UpdateData(FALSE);//并显示出来 } } void CCalculatorDlg::OnClear() { // TODO: Add your control notification handler code here op=NULL; //清空符号 numfirst=0;//清空第一个数字 numsecond=0;//清空第二个数字 point_flag=FALSE;//改为默认整数位 poz=1;//小数点归位 m_Dis=0; UpdateData(FALSE); //屏幕显示归0 } void CCalculatorDlg::OnMin() { // TODO: Add your control notification handler code here { //根据numfirst和numsecond和op的值分为5种状态。 if(numfirst!=0 && numsecond==0&&op=='+') { numsecond=m_Dis; numfirst=numfirst+numsecond; //之前按的是加把两个数赋值到前一个数 m_Dis=numfirst;//赋值给屏幕 numsecond=0; //从新赋值为0,清空,不影响下一次判断 UpdateData(FALSE); m_Dis=0; //屏幕的值同时清空 } if(numfirst!=0 && numsecond==0&&op=='-') { numsecond=m_Dis; numfirst=numfirst-numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst!=0 && numsecond==0&&op=='*') { numsecond=m_Dis; numfirst=numfirst*numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst!=0 && numsecond==0&&op=='/') { numsecond=m_Dis; numfirst=numfirst/numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst==0 && numsecond==0) { //该状态为程序启动还没有开始录入输入的状态 numfirst=m_Dis; //屏幕的值赋值到numfirst UpdateData(FALSE); m_Dis=0; } op='-'; //最后记录最后一个操作是+ poz=1;//小数点位置归位 point_flag=FALSE;//默认小数点标志为整数,也就是0,也就是FALSE } } void CCalculatorDlg::OnMul() { // TODO: Add your control notification handler code here { //根据numfirst和numsecond和op的值分为5种状态。 if(numfirst!=0 && numsecond==0&&op=='+') { numsecond=m_Dis; numfirst=numfirst+numsecond; //之前按的是加把两个数赋值到前一个数 m_Dis=numfirst;//赋值给屏幕 numsecond=0; //从新赋值为0,清空,不影响下一次判断 UpdateData(FALSE); m_Dis=0; //屏幕的值同时清空 } if(numfirst!=0 && numsecond==0&&op=='-') { numsecond=m_Dis; numfirst=numfirst-numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst!=0 && numsecond==0&&op=='*') { numsecond=m_Dis; numfirst=numfirst*numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst!=0 && numsecond==0&&op=='/') { numsecond=m_Dis; numfirst=numfirst/numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst==0 && numsecond==0) { //该状态为程序启动还没有开始录入输入的状态 numfirst=m_Dis; //屏幕的值赋值到numfirst UpdateData(FALSE); m_Dis=0; } op='*'; //最后记录最后一个操作是+ poz=1;//小数点位置归位 point_flag=FALSE;//默认小数点标志为整数,也就是0,也就是FALSE } } void CCalculatorDlg::OnDiv() { // TODO: Add your control notification handler code here { //根据numfirst和numsecond和op的值分为5种状态。 if(numfirst!=0 && numsecond==0&&op=='+') { numsecond=m_Dis; numfirst=numfirst+numsecond; //之前按的是加把两个数赋值到前一个数 m_Dis=numfirst;//赋值给屏幕 numsecond=0; //从新赋值为0,清空,不影响下一次判断 UpdateData(FALSE); m_Dis=0; //屏幕的值同时清空 } if(numfirst!=0 && numsecond==0&&op=='-') { numsecond=m_Dis; numfirst=numfirst-numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst!=0 && numsecond==0&&op=='*') { numsecond=m_Dis; numfirst=numfirst*numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst!=0 && numsecond==0&&op=='/') { numsecond=m_Dis; numfirst=numfirst/numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst==0 && numsecond==0) { //该状态为程序启动还没有开始录入输入的状态 numfirst=m_Dis; //屏幕的值赋值到numfirst UpdateData(FALSE); m_Dis=0; } op='/'; //最后记录最后一个操作是+ poz=1;//小数点位置归位 point_flag=FALSE;//默认小数点标志为整数,也就是0,也就是FALSE } } void CCalculatorDlg::OnEou() { // TODO: Add your control notification handler code here { //根据numfirst和numsecond和op的值分为5种状态。 if(numfirst!=0 && numsecond==0&&op=='+') { numsecond=m_Dis; numfirst=numfirst+numsecond; //之前按的是加把两个数赋值到前一个数 m_Dis=numfirst;//赋值给屏幕 numsecond=0; //从新赋值为0,清空,不影响下一次判断 UpdateData(FALSE); m_Dis=0; //屏幕的值同时清空 } if(numfirst!=0 && numsecond==0&&op=='-') { numsecond=m_Dis; numfirst=numfirst-numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst!=0 && numsecond==0&&op=='*') { numsecond=m_Dis; numfirst=numfirst*numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst!=0 && numsecond==0&&op=='/') { numsecond=m_Dis; numfirst=numfirst/numsecond; m_Dis=numfirst; numsecond=0; UpdateData(FALSE); m_Dis=0; } if(numfirst==0 && numsecond==0) { //该状态为程序启动还没有开始录入输入的状态 numfirst=m_Dis; //屏幕的值赋值到numfirst UpdateData(FALSE); m_Dis=0; } op='='; //最后记录最后一个操作是+ poz=1;//小数点位置归位 point_flag=FALSE;//默认小数点标志为整数,也就是0,也就是FALSE } } 总结: 本次MFC计算器的制作,学习到了MFC基本的编程方法,增加了小组开发的团结协作能力。对OOP编程的理解进一步加深。但是程序仍然没存在一定的问题,比如除数不能为0的Exception handle,符号多次点击结果混乱。由于时间仓促,如果有更多的时间,必定这些问题会迎刃而解。通过这次课程设计,以后Windows 应用程序势必会轻车熟路。
OllyDBG v1.10 plugin - StrongOD v0.2.6 by 海风月影[CUG] ==================================================================== [2009.09.01 v0.2.6.413] 1,添加加载微软符号库的选项 2,Cmdbar增加命令MSG,显示消息号 [2009.08.26 v0.2.6.410] 1,集成Command Bar功能(快捷改成ALT+F1),可以抛弃cmdbar插件了 2,Cmdbar和TBAR插件兼容 [2009.08.24 v0.2.6.405] 1,全面支持win7(7600以下版本不支持) 2,增强解析PE的稳定性 3,修复tmd壳某些时候attach上去无法下断点的漏洞 [2009.06.16 v0.2.5.388] 1,增加ring0稳定性 2,尝试杀掉NP线程 [2009.06.13 v0.2.5.384] 1,修复驱动几个bug,去掉字符串 2,稳定性增加,不再需要key [2009.04.24 v0.2.4.364] 1,驱动有很大改动,加了一些功能,与以前的StrongOD不兼容,更新后需要重启机器 2,启动时检查ollydbg的可疑线程 3,继续修改attach功能 4,修复加壳后无法使用远程注入的功能 [2009.04.03 v0.2.4.350] 1,修复驱动在某些2000下蓝屏的BUG 2,修复驱动的几个BUG 3,加key验证,需要StrongOD.key才能运行 [2009.03.30 v0.2.4.347] 1,修复vista下attach异常的问题 2,增强attach的稳定性,Attach后需要F9,然后resume all thread 3,advenummod支持动态卷,网络映射盘 4,vista sp1下无法打开文件的bug 5,vista下父进程修改 [2009.03.17 v0.2.4.341] 1,退出OD去掉ZwOpenThread的hook 2,修复OD处理codebase会崩溃的BUG 3,驱动不会影响非OD调试程序的情况 [2009.03.09 v0.2.3.328] 1,增强进程保护(保护线程),省得老毛子麻烦 2,修复一个导入表分析的错误 3,修复处理重定位表的BUG 4,修复attach notepad.exe的BUG 5,修复处理导出表的bug 6,修复处理tls的BUG [2009.02.14 v0.2.3.314] 1,修复了2003 sp1下蓝屏bug(感谢cxh852456) 2,增强快捷兼容性,支持简单修改版的OD [2009.02.10 v0.2.3.305] 1,修复几个小BUG 2,增强attach功能 3,修复某个BUG [2009.02.04 v0.2.3.301] 1,底部快捷栏自动记录是否隐藏 2,底部状态栏显示Memory窗口状态 3,修复驱动不加载的bug [2009.02.01 v0.2.3.299] 1,增加多个内存窗口的快速切换,快捷 alt+1 ~ alt+5 2,增加切换堆栈窗口关联到ebp寄存器或者不关联任何寄存器,快捷 alt+1 ~ alt+3 3,增加一个底部的快捷栏,上面有快速切换的按钮,Option里面可以取消创建这个快捷栏, 如果创建后可以用Alt+R来显示,隐藏快捷栏 4,底部的快捷栏是否创建,不影响上面快速切换的功能(没有按钮可以用快捷来切换) [2009.01.14 v0.2.2.292] 1,修复一些解析PE的小bug 2,修复内存断点判断的一个小bug [2009.01.14 v0.2.2.283] 1,修复一些小bug 2,修复驱动一个bug [2009.01.11 v0.2.2.275] 1,增加选项删除入口点断点 2,增加选项断在Tls入口(如果有的话),必须选上Kill Pe Bug 3,增加选项断在进ring3的第一行代码(是否实现,待定) 4,配置文件增加OrdFirst,决定mfc42的导出函数是序号优先还是名字优先 5,修复处理重定位表的bug 6,Attach窗口的鼠标滚轮改成WM_VSCROLL消息 [2009.01.08 v0.2.1.273] 1,修正处理导出表和导入表的bug 2,修正处理重定位表的bug 3,修复Skip Some Expection选上的时候对内存段下F2断点无法正常断下的bug 4,修复Skip Some Expection选上的时候内存断点无法断下的BUG 5,修复IAT序号找不到函数名的BUG [2009.01.06 v0.2.1.262] 1,增加Attach窗口的鼠标滚轮支持 2,重写od处理模块的代码 [2008.12.30 v0.2.1.252] 1,修复驱动BUG [2008.12.25 v0.2.1.235] 1,修复一个利用PAGE_GUARD的anti 2,修复Skip Some Expection选上的时候无法对内存段下F2断点 3,由于PAGE_GUARD的特殊性,无法完美处理od用PAGE_GUARD下断点的BUG,建议尽量不要对内存段下F2断点 4,加强进程保护功能,防止ring3下复制句柄打开od进程 5,修复驱动多处小bug 6,更新版本号 [2008.11.06 v0.20] 1,超长异常处理链导致OD打开太慢的BUG [2008.11.03 v0.19] 1,增加一个快捷,cpudump 窗口 alt+左双击 2,修复隐藏OD窗口后输入法有可能无法使用的BUG 3,修复了一个潜在的蓝屏BUG [2008.09.15 v0.18] 1,修复了Ctrl+G计算rva,offset时的一个小BUG 2,当程序不是运行的状态时,Detach前会先运行程序 3,修复原版OD的数据区复制BUG 4,修复od运行后CPU占用率很高的BUG 5,可以设置是否跳过一些异常处理 [2008.09.02 v0.17] 1,跳过不是OD设的Int 3断,跳过STATUS_GUARD_PAGE,STATUS_INVALID_LOCK_SEQUENCE异常 2,正确处理int 2d指令 [2008.08.31 v0.16] 1,加入驱动,保护进程,隐藏窗口,过绝大部分反调试 2,驱动支持自定义设备名(ollydbg.ini的DeviceName,设备名不超过8个字符) ollydbg.ini的[StrongOD],可以自己设定 HideWindow=1 隐藏窗口 HideProcess=1 隐藏进程 ProtectProcess=1 保护进程 DriverKey=-82693034 和驱动通信的key DriverName=fengyue0 驱动设备名(不超过8个字符) 3,将OD创建进程的父进程改成explorer.exe (抄自shoooo的代码) [2008.08.10 v0.15] 1,增强查找模块功能(能正确查找处理过peb的模块,比如ring3的隐藏模块) 2,增强OD对文件Pe头的分析(如Upack壳等) 3,anti anti attach (一种极端的attach方式) 4,脱离目标程序不再调试(DebugActiveProcessStop)功能,xp系统以上 5,注入dll到被调试的进程 a) Remote Thread(使用CreateRemoteThread注入) b) Current Thread(shellcode,不增加线程方式注入,当前线程必须暂停) [2008.07.04 v0.14] 1,过VMP 1.64邪恶anti 下载地址:http://www.unpack.cn/viewthread.php?tid=26870 [2008.01.20 v0.13] 1,Advanced Ctrl + G 功能可以输入API名(已经和OD自带的功能一摸一样了) 2,修复了当没有断点的时候会有删除所有断点的选项的BUG 3,修复了删除所有断点,有可能删不完的BUG 4,当线程小于或等于1的时候,不会有Resume all thread 和 Suspend all thread选项 5,并不兼容看雪9.21版本(因为这个版本修改了ACPUASM等类名,如果自己修改的版本请不要修改ACPU这样的类名) 6,和加壳版的OD有一定的兼容性(载入时将导入表写回PE头和相应的位置,但还是不支持TheODBG) [2008.01.15 v0.12] 1,增加了Advanced Ctrl + G 功能 2,将浮点bug作为选项(patch代码的,需要重启才能保存选项) 3,将原本patch的代码都取消,全部改成hook形式,增加兼容性(后续的功能将都用patch的形式做) [2007.11.15 v0.11] 去除了2个BUG: 1,启动程序时,如果目录有空格会有个出错信息 2,CPU DUMP 窗口,如果选一个内存块的第一个字节,Infoline会显示异常 增加: 如果断点窗口没有任何断点,则不显示菜单 [2007.11.14 v0.10] 增加创建进程模式 本插件提供了3种方式来启动进程: 1,Normal 和原来的启动方式相同,清掉了STARTINFO里面不干净的数据 2,CreateAsUser 用一个User权限的用户来启动进程,使进程运行在User权限下,无法对Admin建立的进程进行操作 运行这个需要在本地安全策略-用户权利指派里面将你的用户加入2个权限: 1,替换进程级记号(SeAssignPrimaryTokenPrivilege) 2,以操作系统方式操作(SeTcbPrivilege) 如果是home版的windows,无法设置,那么可以试试使用SuperMode,重启OD来提升权限,强烈不建议使用这个选项 3,CreateAsRestrict 第二个选项用User权限的用户来启动进程限制的地方比较多,所以,增加第三个功能,以一个限制级的Admin用户来启动程序 启动的程序是以Admin的用户,不过权限只剩下默认User用户有的权限,一些危险权限全部删除(包括SeDebugPrivilege,SeLoadDriverPrivilege等),这样运行的程序不会对OD造成很大的伤害。建议用这个方式启动程序。 注意: 1,新增加的这2个启动方式,不一定能运行所有的程序(比如OllyDbg)!不过在调试木马的时候会有不错的效果。 2,和 Olly Advanced 插件冲突,加载了Olly Advanced 插件,此功能失效! 隐藏调试器功能 HidePEB,去掉PEB的调试标记,并且从根本上解决了HeapMagic的问题(参考的Phant0m.dll) 此功能的选项选不选都自动隐藏 快捷功能 1. 增加CPU ASM,CPU DUMP,CPU STACK窗口增加Enter相关的一系列快捷 CPU ASM窗口 例如 1000481A |. A3 F48E0010 mov dword ptr ds:[10008EF4], eax 选这行时,按Enter, 表示在 CPU DUMP窗口显示10008EF4位置 按Shift+Enter, 表示在 CPU ASM 窗口显示10008EF4位置 按Ctrl+Enter, 表示在CPU DUMP窗口显示这行的地址1000481A位置 如果有2个立即数,比如 1000481A mov dword ptr ds:[10001000],40304C 这样的语句,如果要切换另一个立即数,就加上Alt,进行切换 选这行时,按Enter, 表示在 CPU DUMP窗口显示40304C位置 按Shift+Enter, 表示在 CPU ASM 窗口显示40304C位置 按Ctrl+Enter, 表示在 CPU DUMP窗口显示这行的地址1000481A位置 按Alt+Enter, 表示在 CPU DUMP窗口显示10001000位置 按Alt+Shift+Enter, 表示在 CPU ASM 窗口显示10001000位置 CPU DUMP窗口 按Enter,表示在CPU ASM窗口显示选的第一个字节开始的数据内容 按Shift+Enter,表示在CPU DUMP窗口显示选的第一个字节开始的数据内容 按Ctrl+Enter,表示在CPU ASM窗口显示选的第一个字节的地址 CPU STACK窗口 按Enter,表示在CPU ASM窗口显示选行的数据 按Shift+Enter,表示在CPU DUMP窗口显示选行的数据 按Ctrl+Enter,表示在CPU ASM窗口显示选行的地址 按Alt+Enter,表示在CPU DUMP窗口显示选行的地址 2. 增加CPU ASM , CPU DUMP , CPU STACK窗口快捷ESC和`(注:ESC下面的),此按功能同在CPU窗口按-(减号)+(加号)功能.(方便笔记本,因为笔记本没有小盘) 3. 增加CPU REG窗口快捷ESC和`(注:ESC下面的)实现View FPU,View MMX,View 3D Now!,View Debug的快速翻页. 4. 增加CPU STACK窗口快捷ESC和`(注:ESC下面的),ESC表示在CPU STACK窗口显示ESP值,`表示显示EBP的值 5. 增加CPU REG窗口快捷CTRL+数字1至8(分别对应EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI)将其内容显示在CPUASM窗口 增加CPU REG窗口快捷SHIFT+数字1至8(分别对应EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI)将其内容显示在CPUDUMP窗口 6. 增加CPU ASM,CPU DUMP窗口快捷Shift+C,Shift+V,Shift+X,Ctrl+X.分别对应二进制复制,二进制粘贴,无空格二进制复制(方便写OD脚本的兄弟),复制选的第一个字节的地址 注:Shift+V 只需要选起始地址即可. Shift+C与Shift+X的区别如下: 55 8B EC 8B 45 0C 48 74 42 48 74 37 83 E8 0D 74 558BEC8B450C48744248743783E80D74 Ctrl+X功能是复制选的第一个字节的地址,如选的第一行是 1000481A mov dword ptr ds:[10001000],40304C 按Ctrl+X,则地址01000481A 复制到剪贴板 7. 增加在CPU ASM 和CPU DUMP窗口增加快捷Insert ,Delete Insert 将选的区域以0x90填充 Delete 将选的区域以0x00填充 先选一块区域,然后按,填充完后可以用OD的恢复功能恢复(Alt + Backspace) 8. 增加状态栏显示CPU DUMP窗口区域的起始地址,结束地址,选区域大小,及当前值. 注:如CPU DUMP窗口数据为00401000 00 10 40 00 69 6E 67 20 鼠标选地址00401000后面的00时,状态栏窗口显示Value为401000,按Ctrl+双击鼠标左复制Value到剪切板. 9. 增加断点窗口(ALT+B呼出)Delete All BreakPoints功能.实现删除全部断点. 10. 增加线程窗口Suspend All Threads,Resume All Threads功能.实现挂起和恢复全部线程. 特别感谢:fly,sucsor,lifeengines,shoooo,foxabu,hellsp@wn,okdodo,kanxue,a__p,微笑一刀,goldsun

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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