精华内容
下载资源
问答
  • 1、实验目的和要求 (1)创建一默认的对话框应用程序Ex_Ctrls,如图2.1所示。 (2)设计如图2.2所示的“课程信息”对话框
  • 用mfc开发一简单的科学计算器程序,采用的是基于对话框模式的应用程序,具有加、减、乘、除四基本功能,并在此基础上扩展平方、开方、三角函数等功能。可以放在自己电脑上使用,比较方便。
  • mfc 采用基于对话框的应用程序类型设计对话框,功能实现了建立模态对话框以及非模态对话框,形象的描述了二者的差别
  • 易语言WIN32程序设计对话框源码,WIN32程序设计对话框,取低十六位,GetModuleHandle,DialogBoxParam,EndDialog,LoadIcon,SendMessage,ExitProcess
  • 设计上网问卷调查对话框 1按教程的步骤先将该对话框应用程序上机练习并通过 2添加一静态文本控件标题为你每天上网的平均时间保留默认的标识符 3添加4单选按钮控件在其属性对话框中分别将其标题设置为小时小时...
  • WIN32程序设计对话框.rar
  • CCHWinForms应用程序对话框设计PPT教学课件.pptx
  • 创建对话框主要分两大步:第一,创建对话框资源,主要包括创建新的对话框模板、设置对话框属性和为对话框添加各种控件;... 一、采用基于对话框的应用程序类型设计对话框 目的:设计模态与非模态对话框 ...

    创建对话框主要分两大步:第一,创建对话框资源,主要包括创建新的对话框模板、设置对话框属性和为对话框添加各种控件;

                                                第二,生成对话框类,主要包括新建对话框类、添加控件变量和控件的消息处理函数等。
     

                       采用基于对话框的应用程序类型设计对话框

    目的:设计模态与非模态对话框

    区分模态与非模态:

                      1、模态对话框垄断了用户的输入。当一个模态对话框打开时,用户只能与该对话框进行交互,而其他用户界面对象   收不到输入信息。模态对话框下,用户需要操作目标对话框就必须先操作模态对话框。
                      2、非模态对话框(Nonmodal Dialogue Box,又叫做无模式对话框),与模态对话框不同,当用户打开非模态对话框时,依然可以操作其他窗口。

    简而言之,模态对话框就是你只能操作当前的对话框,非模态就是你随便。

    step1:建立工程

    可以直接点击完成!!!

    step2:准备工作做好

    以及还要用到:


     

    step3:添加button

    改名:可以通过captain修改其名亦或直接输入内容

    ①第一种方法:

    点一下Button1(点一下啊!!)会出现属性栏,或者点击右键属性

    ②第二种方法:

    选中,然后直接打字按空格就完了

     

    然后再加俩对话框不要忘记改ID:

     

    添加的第二个对话框:

     

    并改其ID为SIMU

    step4 :右键添加类

    先弄模态的对话框

     

    step5:添加控件事件

    方法一:右键属性,点击触发事件 

    方法二:闪电图表

      方法三、双击按钮(建议直接双击模态)

    接下来要弹出模态对话框,首先加头文件(加那个你添加的类的名的头文件):

    运行一下看看(你会发现这里你不能操作第一个对话框,所以这是模态对话框):

     

    step6.非模态的创建  

    先添加类:

    双击非模态对话框(添加控件事件)

    然后添加代码:

    先引头文件:

    然后:

    点击运行:

    改进:

    这样也只能点非模态对话框一次,如何点多次?(创建一次对话框,那么就不会崩掉了)

    运行:

    OK,大功告成!!

    展开全文
  • 主要介绍了C++基于对话框程序的框架,以实例形式讲述了C++对话框程序框架,有助于深入理解基于C++的Windows程序设计,需要的朋友可以参考下
  • MFC 对话框程序设计

    千次阅读 2017-01-23 23:49:10
    MFC 对话框程序设计

    1.1 CDialog简单笔记


    用来管理对话框控件的CWnd成员函数 

     函数名 

     功能 

     CheckDlgButton 

     选中或不选中按钮控件。 

     CheckRadioButton 

     选择一个指定的单选按钮并使同组内的其它单选按钮不被选择。 

     DlgDirList 

     往一个列表框中添加文件、目录或驱动器的列表。 

     DlgDirListComboBox 

     往一个组合框中的列表框内添加文件、目录或驱动器的列表。 

     DlgDirSelect 

     从一个列表框中获得当前选择的文件、目录或驱动器。 

     DlgDirSelectBomboBox 

     从一个组合框中获得当前选择的文件、目录或驱动器。 

     GetCheckedRadioButton 

     返回指定的单选按钮组中被选择的单选按钮的ID。 

     GetDlgItem 

     返回一个指向一给定的控件的临时对象的指针。 

     GetDlgItemInt 

     返回在一个指定的控件中由正文表示的数字值。 

     GetDlgItemText 

     获得在一个控件内显示的正文。 

     GetNextDlgGroupItem 

     返回一个指向一组控件内的下一个或上一个控件的临时对象的指针。 

     GetNextDlgTabItem 

     返回下一个tab顺序的控件的临时对象的指针。 

     IsDlgButtonChecked 

     返回一个按钮控件的状态。 

     SendDlgItemMessage 

     把一个消息传送给一个控件。 

     SetDlgItemInt 

     将一个整数转换为正文,并将此正文赋给控件。 

     SetDlgItemText 

     设置一个控件显示的正文。 

    1.2 对话框消息处理技巧

    有时,为了处理方便,需要把多个ID连续的控件发出的相同消息映射到同一个处理函数上.这就要用到ON_CONTROL_RANGE宏.ON_CONTROL_RANGE消息映射宏的第一个参数是控件消息码,第二和第三个参数分别指明了一组连续的控件ID中的头一个和最后一个ID,最后一个参数是消息处理函数名。例如,要处理一组单选按钮发出的BN_CLICKED消息,相应的消息映射如下所示: 

    ON_CONTROL_RANGE(BN_CLICKED, IDC_FIRST, IDC_LAST,OnRadioClicked) 

    函数OnRadioClicked的声明如下,该函数比上面的OnAdd多了一个参数nID以说明发送通知消息的控件ID. 

    afx_msg void OnRadioClicked(UINT nID); 

    ClassWizard不支持ON_CONTROL_RANGE宏,所以需要手工建立消息映射和消息处理函数. 

     

    提示:事实上,在使用ClassWizard时只要运用一个小小的技巧,就可以把不同控件的通知消息映射到同一个处理函数上,也可以把一个控件的不同通知消息映射到同一个处理函数上.这个技巧就是在用ClassWizard创建消息处理函数时,指定相同的函数名即可.此方法的优点在于控件的ID不必是连续的,缺点是处理函数没有nID参数,因而不能确定是哪一个控件发送的消息.

    1.3 动态创建按钮(CButton-Create)

    CButton::Create

     

    xxx.h

     

    private:

           CButtonm_Btn;

            BOOL m_IsbCreated;//判断是否创建,开始一定要在构造函数中设置为FALSE

    ///

     

    xxx.cpp

     

    void CCDialogTestDlg::OnBnClickedButton1()

    {

           //TODO:  在此添加控件通知处理程序代码

           if(m_IsbCreated == FALSE)

           {

                  m_Btn.Create(_T("动态创建的按钮"), WS_VISIBLE | WS_CHILD |BS_DEFPUSHBUTTON, CRect(0, 0, 150, 50), this, 12333);

                  m_IsbCreated= TRUE;

           }

           else

           {

                  m_Btn.DestroyWindow();

                  m_IsbCreated= FALSE;

           }

           //m_Btn.ShowWindow(SW_SHOW);

    }

    --------------------------------------------------------------------------------------------------

    1.4 对话框伸缩功能的实现

    添加图片控件并设置ID为IDC_SEPARATOR,属性中Sunken为TRUE。

     

    void CCDialogTestDlg::OnBnClickedButton2()

    {

           // TODO:  在此添加控件通知处理程序代码

           CString str;

           GetDlgItemText(IDC_BUTTON2, str);

           if (str == "扩展窗口>>")

           {

                  SetDlgItemText(IDC_BUTTON2, _T("收缩窗口<<"));

           }

           else

           {

                  SetDlgItemText(IDC_BUTTON2, _T("扩展窗口>>"));

           }

           static CRect rectLarge;

           static CRect rectSmall;

           if(rectLarge.IsRectNull())

           {

                  CRect rectSeparator;

                  GetWindowRect(&rectLarge);

                  GetDlgItem(IDC_SEPARATOR)->GetWindowRect(&rectSeparator);  //本例为横分割,列分割主要改一下就可以

                  rectSmall.left= rectLarge.left;

                  rectSmall.top= rectLarge.top;

                  rectSmall.right= rectLarge.right;

                  rectSmall.bottom= rectSeparator.bottom;

           }

           if (str == "收缩窗口<<")

           {

                  SetWindowPos(NULL, 0, 0,rectSmall.Width(), rectSmall.Height(),SWP_NOMOVE|SWP_NOZORDER);

           }

           else

           {

                  SetWindowPos(NULL, 0, 0,rectLarge.Width(), rectLarge.Height(), SWP_NOMOVE | SWP_NOZORDER);

           }

    }

    --------------------------------------------------------------------------------------------------

    附加:

    1.5 属性表单和向导的创建

    使用类CpropertyPage、

    CObject

     └CCmdTarget

        └CWnd

           └CDialog

              └CpropertyPage

    步骤:

    根据属性页页数插入多个资源CDialog,属性页资源有三种类型(大、中、小)

    备注:分别为各个页创建对话框模板,去掉缺省的OK和Cancel按钮。每页的模板最好具有相同的尺寸,如果尺寸不统一,则框架将根据最大的页来确定标签对话框的大小。

    属性页的设置(与普通对话框属性不同)

    指定标题(Caption)的内容。标题的内容将显示在该页对应的标签中。 

    选择System menu—False、TitleBar---True、Style--Child、Border--ThinBorder和Disable ---True。 

    根据各个页的模板,用ClassWizard分别为每个页创建CPropertyPage类的派生类。这一过程与创建普通对话框类的过程类似,不同的是在创建新类对话框中应在Base class一栏中选择CPropertyPage而不是CDialog。 

    用ClassWizard为每页加入与控件对应的成员变量,这个过程与为普通对话框类加入成员变量类似。

    注意:为了构建一个属性表单,首先需创建一个Cproperty Sheet对象,在该对象头文件中添加

    // CPropSheet

    #include "Prop1.h"

    #include "Prop2.h"

    #include "Prop3.h"

    .........................

    public:

           CProp1 m_prop1;

           CProp2 m_prop2;

    CProp3 m_prop3;

    --------------------------------------------------------------------------------------------------

    然后在构造函数中调用AddPage添加属性页

    CPropSheet::CPropSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)

           :CPropertySheet(nIDCaption, pParentWnd, iSelectPage)

    {

           AddPage(&m_prop1);

           AddPage(&m_prop2);

           AddPage(&m_prop3);

    }

    CPropSheet::CPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)

           :CPropertySheet(pszCaption, pParentWnd, iSelectPage)

    {

           AddPage(&m_prop1);

           AddPage(&m_prop2);

           AddPage(&m_prop3);

    }

    --------------------------------------------------------------------------------------------------

    注意:有两个构造函数,参数不一样。

    典型的标签式对话框创建代码:

    void CMyView::DoModalPropertySheet() 

     { 

     CPropertySheet propsheet; 

     CMyFirstPage pageFirst; // derived from CPropertyPage 

     CMySecondPage pageSecond; // derived fromCPropertyPage 

     

     // Move member data from the view (or from thecurrently 

     // selected object in the view, for example). 

     pageFirst.m_nMember1 = m_nMember1;  

     pageFirst.m_nMember2 = m_nMember2; 

     pageSecond.m_strMember3 = m_strMember3; 

     pageSecond.m_strMember4 = m_strMember4;  

     propsheet.AddPage(&pageFirst); 

     propsheet.AddPage(&pageSecond); 

     if (propsheet.DoModal() == IDOK) 

     { 

     m_nMember1 = pageFirst.m_nMember1; 

     m_nMember2 = pageFirst.m_nMember2; 

     m_strMember3 = pageSecond.m_strMember3; 

     m_strMember4 = pageSecond.m_strMember4;  

     . . .  

     } 

     }

    --------------------------------------------------------------------------------------------------

    向导的创建

    但是步骤5创建的表单有问题,比如第一个属性页就不应该有“上一步”的按钮,所以还要设置如下:

    // CProp2 message handlers

    BOOL CProp2::OnSetActive()

    {

           // TODO: Add your specialized code here and/or call thebase class

           ((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);

           return CPropertyPage::OnSetActive();

    }

    --------------------------------------------------------------------------------------------------

    1.   处理各个属性页(注意判断用户是否选中各个属性页的选项)

    LRESULT CProp2::OnWizardNext()

    {

           // TODO: Add your specialized code here and/or call thebase class

           UpdateData();

           if(    m_football || m_basketball || m_volleyball|| m_swim)

                  return CPropertyPage::OnWizardNext();

           else

           {

                  MessageBox("请选择你的兴趣爱好!");

                  return -1;

           }

    }

    --------------------------------------------------------------------------------------------------

    2.   完成向导:在最后一个属性页中最后调用函数

    BOOL CProp3::OnWizardFinish()

    {

           // TODO: Add your specialized code here and/or call thebase class

           int index;

           index=((CComboBox*)GetDlgItem(IDC_COMBO3))->GetCurSel();

           ((CComboBox*)GetDlgItem(IDC_COMBO3))->GetLBText(index,m_strSalary);

          

           return CPropertyPage::OnWizardFinish();//重点

    }

    --------------------------------------------------------------------------------------------------

    1.6 对话框位置和大小设置

    1.6.1 限制对话框大小

    主要是afx_msg void OnSize(UINT nType, int cx, int cy);的使用

     

    voidCRestrictRectDlg::OnSize(UINT nType, int cx, int cy)

    {

           CDialog::OnSize(nType, cx, cy);

          

           // TODO: Add your message handler codehere

           CRect rect;

           GetWindowRect(&rect);//获取窗口矩形区

           if(cx > 400)

                  rect.right = rect.left + 400;//窗体宽度不能大于400

           if(cy > 300)

                  rect.bottom = rect.top + 300;//窗体高度不能大于300

           if(cx < 200)

                  rect.right = rect.left + 200;//窗体宽度不能小于200

           if(cy < 150)

                  rect.bottom = rect.top + 150;//窗体高度不能小于150

           MoveWindow(&rect);//修改窗体大小

    }

    --------------------------------------------------------------------------------------------------

    1.6.2 限制最大化时窗体大小

    主要是这个函数:afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);

     

    voidCLimitSizeDlg::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)

    {

           lpMMI->ptMaxSize.x = 800;    //设置对话框最大化时的宽度

           lpMMI->ptMaxSize.y = 600;    //设置对话框最大化时的高度

     

           lpMMI->ptMaxPosition.x = 50; //设置对话框最大化时左边位置

           lpMMI->ptMaxPosition.y = 50; //设置对话框最大化时上访位置

           CDialog::OnGetMinMaxInfo(lpMMI);

    }

    --------------------------------------------------------------------------------------------------

    注意,可类似制作最小化时窗体大小。

    1.6.3 发送最大化或最小化消息

    voidCMaxAndMinDlg::OnButton1()

    {

           PostMessage(WM_SYSCOMMAND,SC_MAXIMIZE,0);

    }

     

    voidCMaxAndMinDlg::OnButton2()

    {

           PostMessage(WM_SYSCOMMAND,SC_MINIMIZE,0);

    }

    -------------------------------------------------------------------------------------------------

    1.6.4 对话框窗口变化时控件适应大小

    使用从CDialog派生的一个类cdxCSizingDialog,用于实现可改变大小的对话框,具体要参见源代码。

    1.6.5 始终在最上面的窗体

    BOOLCTopWindowDlg::OnInitDialog()

    {

           .....................

           SetIcon(m_hIcon, TRUE);               // Set big icon

           SetIcon(m_hIcon, FALSE);       // Set small icon

          

           //始终在最上面的窗体

    ::SetWindowPos(AfxGetMainWnd()->m_hWnd,HWND_TOPMOST,10,10,450,300,SWP_NOMOVE);

           return TRUE;  // return TRUE  unless you set the focus to a control

    }

    -------------------------------------------------------------------------------------------------

    1.7 自绘对话框

    可以根据具体的要求自己绘制美观的对话框,具体参见源代码。

    1.8 换肤窗体

    主要是一个组件库的使用,具体参见源代码。

    1.9 对话框背景

    1.9.1 位图背景

    方法一:准备一张位图,主要是在OnPaint()中添加位图。

     

    voidCBmpBKDlg::OnPaint()

    {

           ................

           else

           {

                  CPaintDC dc(this);      //窗体DC

                  CBitmap m_bitmap;    //位图变量

                  m_bitmap.LoadBitmap(IDB_BITMAP1);//载入位图资源

                  CDC memdc;       //临时DC

                  memdc.CreateCompatibleDC(&dc);//创建临时DC

                  memdc.SelectObject(&m_bitmap);//选中位图对象

                  int width,height;//定义位图宽度和高度

                  BITMAP bmp;

                  m_bitmap.GetBitmap(&bmp);//获取位图信息

                  width = bmp.bmWidth;//位图宽度

                  height = bmp.bmHeight;//位图高度

                  CRect rect;

                  this->GetClientRect(&rect);//获取窗体大小

                  //将位图绘制在窗体上作为背景

           dc.StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memdc,0,0,width,height,SRCCOPY);       }

    }

    -------------------------------------------------------------------------------------------------

     

    方法二:实现CWnd::OnEraseBkgnd消息函数

    BOOLCShowImageDlgDlg::OnEraseBkgnd(CDC *pDC)

    {    

          CRect rect;

          GetClientRect(&rect);

          CDC memDC;

          CBitmap cbmp;

          CBitmap* bmp = NULL;

          cbmp.LoadBitmap(IDB_MYBITMAP);//装载背景位图

          BITMAP bmInfo;

          cbmp.GetBitmap(&bmInfo);

          memDC.CreateCompatibleDC(pDC);

          bmp = memDC.SelectObject(&cbmp);

          //pDC->BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);

    pDC->StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,0,0,bmInfo.bmWidth,bmInfo.bmHeight,SRCCOPY);

          if (bmp) memDC.SelectObject(bmp);

          return TRUE;

    }

    -------------------------------------------------------------------------------------------------

    注:还可使用第三方的类,具体见源代码。

     

    1.9.2 使用笔刷绘制背景

    HBRUSHCBrushBKDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

    {

           HBRUSH hbr = CDialog::OnCtlColor(pDC,pWnd, nCtlColor);

          

           // TODO: Change any attributes of the DChere

           CBrush m_brush; //定义画刷

           m_brush.CreateSolidBrush(RGB(255,0,0));//指定画刷颜色

           CRect m_rect;

           GetClientRect(m_rect);//客户区矩形

           pDC->SelectObject(&m_brush);//选择画刷

           pDC->FillRect(m_rect,&m_brush);//填充矩形区

           return m_brush;

    }

    -------------------------------------------------------------------------------------------------

    1.9.3 渐变色背景

    修改OnPaint()函数即可。

    voidCColorChangeDlg::OnPaint()

    {

           CPaintDC dc(this);

           CBrush brush;

           CRect rect;

           GetClientRect(&rect);

           for(int m=255;m>0;m--)

           {

                  int x,y;

                  x = rect.Width() * m / 255;

                  y = rect.Height() * m / 255;

                  brush.DeleteObject();

                  brush.CreateSolidBrush(RGB(255,m,0));

                  dc.FillRect(CRect(0,0,x,y),&brush);

           }

    }

    -------------------------------------------------------------------------------------------------

    1.9.3 使用CImage类动态加载图片背景

    要使用CImage类,就在对话框类的头文件中定义一个:CImage类

     

    CImagem_DlgBKImage;

     

    再在此对话框的OnInitDialog中进行载入,方法为:

     charLoatFilePath[256] = "C://Documents and Settings//Administrator//桌面//20090728//20090728//23.jpg";
     HRESULT  ImageLoad;
     CRect rect;
     CWnd::GetClientRect(&rect);

     ImageLoad= m_DlgBKImage.Load(LoatFilePath);

    if(0== ImageLoad)

    {

      Messagebox("load file error!");

    }
     InvalidateRect(&rect,TRUE);

     

    再在对话框的OnPaint方法中:

     

     CPaintDCdc(this); // 用于绘制的设备上下文
     CRect rect;
     GetClientRect(&rect);
     if (!m_DlgBKImage.IsNull())
     {
      m_DlgBKImage.StretchBlt(dc,rect);
     }

     //当前目录

    CString m_strPath;

        char chPath[MAX_PATH];

        GetModuleFileName(NULL, chPath, MAX_PATH);  //得到执行程序的文件名(包括路径);

        m_strPath.Format("%s", chPath);                 //转换成字符串;

        int nPos = m_strPath.ReverseFind('\\');     //从右边找到第一个“\\”字符,返回其数组下标的位置

        m_strPath = m_strPath.Left(nPos + 1);       //保留字符串的前nPos+1个字符(包括“\\”);

        m_strPath+= "test.bmp";

        //char LoatFilePath[256] =m_strPath+"test.bmp";

        HRESULT  ImageLoad;

        CRect rect;

        CWnd::GetClientRect(&rect);

        ImageLoad = m_DlgBKImage.Load(m_strPath);

    展开全文
  • Delphi面向对象程序设计课件
  • VB程序设计对话框设计PPT课件.pptx
  • 详细介绍了autolisp程序设计中的对话框设计知识,对于初学者来说简单易懂
  • C++对话框程序设计

    2012-09-01 10:36:41
    MFC C++程序设计 MFC程序设计
  • android库,创建完全材料设计的底部对话框类似于android支付应用程序
  • 程序设计教程对话框设计和Windows常用控件PPT课件.pptx
  • 易语言源码易语言WIN32程序设计对话框源码.rar
  • 基于模板的对话框,包含了弹出窗口,和子窗口控件,而且有一窗口过程来处理对话框消息。 包括键盘和鼠标的输入。 称为 “对话框管理器” 和标准的Windows窗口消息处理略有不同。稍后能看到具体区别 许多消息不仅...

    第十一章  对话框


    基于模板的对话框,包含了弹出窗口,和子窗口控件,而且有一个窗口过程来处理对话框消息。 包括键盘和鼠标的输入。

    称为 “对话框管理器”  和标准的Windows窗口消息处理略有不同。稍后能看到具体区别


    许多消息不仅被对话框窗口过程处理,还会传递给你自己的程序中的某些函数。  称为对话框过程

    对话框过程一般处理初始化自创控件以及子窗口传来的消息。不处理WM_PAINT 也不直接处理键盘和鼠标的输入


    子窗口控件由windows对话框管理器来负责。对话框管理器来负责处理在多个控件中转义输入焦点的相关逻辑


    11.1  模态对话框

    用户不能在该对话框和该程序的其他对话框之间切换。但是可以切换到其他的程序。有些系统模态不允许切换程序。必须结束系统模态才可以进行其他操作。

    11.1.1 创建一个about对话框


    About.cpp

    #include <windows.h>  
    #include "resource.h"   
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.   
    BOOL	CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static      TCHAR szAppName[] = TEXT("About1");    
    	HACCEL      hAccel;
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class        
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.        
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(hInstance, szAppName);// LoadIcon(NULL, IDI_APPLICATION);  
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);    
    	wndClass.lpszMenuName = szAppName;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.         
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	//This function will generate an WM_CREATE message.        
    	hwnd = CreateWindow(szAppName,      //Window class name        
    		TEXT("About Box Demo Program"),      //Window caption        
    		WS_OVERLAPPEDWINDOW,            //Window Style        
    		CW_USEDEFAULT,                  //initial x position        
    		CW_USEDEFAULT,                  //initial y position        
    		CW_USEDEFAULT,                  //initial x size        
    		CW_USEDEFAULT,                  //initial y size        
    		NULL,                           //parent window handle        
    		NULL,                           //window menu handle        
    		hInstance,                      //program instance handle        
    		NULL);                          //creation parameters        
    
    	ShowWindow(hwnd, iCmdShow);
    	UpdateWindow(hwnd); //This function will generate a WM_PAINT message.        
    
    	/* The message loop for this program.
    	if received the WM_QUIT message, the function will return 0.*/
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);	
    	}
    	return msg.wParam;
    
    }
    
    //define the Window Procedure WndProc        
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HINSTANCE hInstance;
    
    	switch (message) //get the message        
    	{
    	case WM_CREATE:
    		hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
    		return 0;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDM_APP_ABOUT:
    			DialogBox(hInstance, TEXT("AboutBox"), hwnd, AboutDlgProc);
    			break;
    		}
    
    		return 0;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    	return  DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		return TRUE;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDOK:
    		case IDCANCEL:
    			EndDialog(hDlg, 0);
    			return TRUE;
    		}
    		break;
    	}
    
    	return FALSE;
    }

    About1.rc

    // Microsoft Visual C++ generated resource script.
    //
    #include "resource.h"
    
    #define APSTUDIO_READONLY_SYMBOLS
    /
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "afxres.h"
    
    /
    #undef APSTUDIO_READONLY_SYMBOLS
    
    /
    // English (United States) resources
    
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
    #pragma code_page(1252)
    
    #ifdef APSTUDIO_INVOKED
    /
    //
    // TEXTINCLUDE
    //
    
    1 TEXTINCLUDE 
    BEGIN
        "resource.h\0"
    END
    
    2 TEXTINCLUDE 
    BEGIN
        "#include ""afxres.h""\r\n"
        "\0"
    END
    
    3 TEXTINCLUDE 
    BEGIN
        "\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // Dialog
    //
    
    ABOUTBOX DIALOGEX 32, 32, 180, 102
    STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP
    FONT 8, "MS Sans Serif", 0, 0, 0x0
    BEGIN
        DEFPUSHBUTTON   "OK",IDOK,66,81,50,14
        ICON            "ABOUT1",IDC_STATIC,7,7,20,20
        CTEXT           "About1",IDC_STATIC,40,12,100,8
        CTEXT           "About Box Demo Program",IDC_STATIC,7,40,166,8
        CTEXT           "(c) Charles Petzold, 1998",IDC_STATIC,7,52,166,8
    END
    
    
    /
    //
    // Menu
    //
    
    ABOUT1 MENU
    BEGIN
        POPUP "&Help"
        BEGIN
            MENUITEM "&About About1...",            IDM_APP_ABOUT
        END
    END
    
    
    /
    //
    // Icon
    //
    
    // Icon with lowest ID value placed first to ensure application icon
    // remains consistent on all systems.
    ABOUT1                  ICON                    "About1.ico"
    
    
    /
    //
    // DESIGNINFO
    //
    
    #ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO
    BEGIN
        "ABOUTBOX", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 173
            TOPMARGIN, 7
            BOTTOMMARGIN, 95
        END
    END
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // AFX_DIALOG_LAYOUT
    //
    
    ABOUTBOX AFX_DIALOG_LAYOUT
    BEGIN
        0
    END
    
    #endif    // English (United States) resources
    /
    
    
    
    #ifndef APSTUDIO_INVOKED
    /
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    
    
    /
    #endif    // not APSTUDIO_INVOKED
    
    
    resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Developer Studio generated include file.
    // Used by About1.rc
    //
    #define IDM_APP_ABOUT                   40001
    
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        104
    #define _APS_NEXT_COMMAND_VALUE         40004
    #define _APS_NEXT_CONTROL_VALUE         1003
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif
    


    11.1.2 对话框及其模板


    DEFPUSHBUTTON, ICON 和CTEXT只被用于对话框。他们是一些特殊类和窗口样式的缩写。  CTEXT指定窗口控件的类型是静态的,同时其样式是

    WS_CHILD | SS_CENTER | WS_VISIBLE | WS_GROUP

    文本设定等价于Caption参数

    当子窗口像父窗口发送WM_COMMAND时,id字段是子窗口用来表示自己的标识符。 子窗口控件的父窗口是对话框本身。它会把这些消息发送给某个windows的窗口过程。

    这里的ID和CreateWindow中 (HMENU)id  参数相同。 由于文本和图标并不需要向父窗口发送消息。所以ID被设定为ID_STATIC 按钮的ID为IDOK   在winuser.h中定义为1

    接下来设定子窗口控件的位置和大小。   单位是 字符评均宽度的1/4 和  平均高度的1/8


    11.1.3 对话框过程

    发送给对话框的消息是用户程序中的对话框过程来处理的。和窗口过程很像,但是其实是不一样的。  对话框的窗口过程属于windows。 而对话框过程是独立的。

    对话框的窗口过程会调用这个对话框的过程来处理许多消息。

    对话框过程

    BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		return TRUE;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDOK:
    		case IDCANCEL:
    			EndDialog(hDlg, 0);
    			return TRUE;
    		}
    		break;
    	}
    
    	return FALSE;
    }
    对话框过程  和 对话框的窗口过程的区别

    1)窗口过程返回值是  LRESULT  而对话框过程的返回值是BOOL

    2)窗口过程不处理一条消息时,会调用DefWindowProc。  对话框过程处理一条消息会返回TRUE,不处理则返回FALSE

    3)  对话框过程不需要处理WM_PAINT和WM_DESTROY消息。他也不会收到WM_CREATE消息。 然后他会在一条处理WM_INITDIALOG消息时进行初始化,这是对话框过程接收到的第一条消息。当其返回TRUE时,windows会把输入焦点放在第对话框第一个含有WS_TABSTOP样式的窗口子空间。本例中是按钮。

    另外在WM_INITDIALOG也可以调用SetFocus来设置焦点,并返回FALSE

    除此之外,对话框过程只处理WM_COMMAND,当鼠标单击按钮或者当焦点在按钮控件时按下空格键,按钮控件会像父窗口发送WM_COMMAND消息。wParam低位时控件ID

    其他任何消息,对话框过程会返回FALSE来通知对话框的窗口过程该消息未处理。

    模态对话框的消息并不通过程序的消息循环。


    11.1.4 激活对话框

    Dialog(hInstance, TEXT("AboutBox"), hwnd, AboutDlgProc);

    实例句柄, 对话框名称在资源该脚本中定义, 父窗口句柄   和对话框过程的地址。

    也可以使用MAKEINTRESOURCE宏来将其转换为字符。


    当回车或空格被按下,windows会向对话框发送WM_COMMAND消息。 wParam的低位时默认按钮ID。 也可以按ESC来结束对话框。

    直到对话框结束以后,用来显示对话框的DialogBox才将控制返回给WndProc。 DialogBox的返回值等于EndDialog函数的第二个参数。并将控制权返回给Windows.


    对话框在显示使,WndProc依旧可以处理消息。比如SendMessage(GetParent(Dlg), ...);


    11.1.5 主题变换

    对话框资源脚本

    对话框常用样式

    STYLE WS_POPUP | DS_MODALFRAME

    带标题栏 WS_CAPTION


    CAPTION "Dialog Box Caption"  标题栏文本

    或者当对话框过程处理WM_INITDIALOG消息时,你可以使用

    SetWindowText(hDlg, TEXT("Dialog Box Caption"));


    使用WS_CAPTION样式 还运行使用WS_SYSMENU 增加系统菜单框。这一样式允许用户通过系统菜单来选择Move或Close


    WS_THICKFRAME   (Resizing) 允许用户改变对话框的大小。甚至还可以给对话框添加菜单

    MENU 菜单名


    FONT 语句用来设置对话框文本为系统字体以外的字体。 早起VS创建对话框默认的字体是 8pt的 MS Scans Serif。  现在VS2015使用的是  8pt的 MS Shell Dlg 字体


    可以指定某个窗口过程来处理对话框消息。

    CLASS “类名”


    调用DialogBox函数, windows会从对话框资源模板中获取信息来CreateWindow ,windows从DialogBox函数的参数获取hInstance 和 父窗口hwnd

    windows所需的唯一其他信息是一个窗口类,假设对话框模板没有指定。  window设为对话框注册一个特殊的窗口类。窗口类用于对话框过程的访问地址。

    因此弹出式窗口可以向程序传递其收到的消息。 也可以自己使用CreateWindow并注册窗口类来创建自己的对话框,DialogBox函数只是一种简便的方法。


    也可以动态创建对话框,不需要写资源脚本。DialogBoxIndirect函数   使用数据结构来定义对话框模板。

    常用控件类型的相应窗口类和窗口样式



    除了表中的样式,每个控件默认还有以下样式

    WS_CHILD | WS_VISIBLE

      EDITTEXT, SCROLLBAR, LISTBOX 和COMBOBOX以下格式

    控件类型 id, xPos, yPos, xWidth, yHeight, iStyle

    除此之外所有控件的定义都有以下格式

    控件类型 "文本" , id, xpos, ypos, xwidth, yHeight, iStyle

    对话框模板中的单位是平均字符宽度的1/4 和  高度的 1/8 。


    例如复选框

    CHECKBOX "TEXT", id, xPos, yPos, xWidth, yHeight, BS_LEFTTEXT      checkbox上的说明文本左对齐


    EDITTEXT id, xPos, yPos, xWidth, yHeight, NOT WS_BORDER        不带边框的EDITTEXT


    资源编辑器还承认这样的一般化语句

    CONTROL  "文本" , id, "类", IStyle, xPos, yPos, xWidth, yHeight

    创建任何类型的子窗口控件

    比如 

    PUSHBUTTON "OK", IDOK, 10, 20, 32, 14

    可以使用下面语句

    CONTROL "OK" , IDOK, "button", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP,

            10, 20, 32, 14

    可使用VS中自定义控件选项来生成以上语句


    在模板资源中,则无需WS_CHILD | WS_VISIBLE 样式

    上面的CONTROL语句转换成如下调用

    hCtrl1 = CreateWindow( TEXT("button"), TEXT("OK"),

                      WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,

                      10 * cxChar / 4,     20 * cyChar / 8,

                      32 * cxChar / 4,     14 * cyChar / 8,

                      hDlg, IDOK, hInstance, NULL);


    11.1.6 更复杂的对话框

    about2.cpp

    #include <windows.h>  
    #include "resource.h"   
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.   
    BOOL	CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
    
    int iCurrentColor = IDC_BLACK,
    iCurrentFigure = IDC_RECT;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static      TCHAR szAppName[] = TEXT("About2");
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class        
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.        
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(hInstance, szAppName);// LoadIcon(NULL, IDI_APPLICATION);  
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndClass.lpszMenuName = szAppName;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.         
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	//This function will generate an WM_CREATE message.        
    	hwnd = CreateWindow(szAppName,      //Window class name        
    		TEXT("About Box Demo Program"),      //Window caption        
    		WS_OVERLAPPEDWINDOW,            //Window Style        
    		CW_USEDEFAULT,                  //initial x position        
    		CW_USEDEFAULT,                  //initial y position        
    		CW_USEDEFAULT,                  //initial x size        
    		CW_USEDEFAULT,                  //initial y size        
    		NULL,                           //parent window handle        
    		NULL,                           //window menu handle        
    		hInstance,                      //program instance handle        
    		NULL);                          //creation parameters        
    
    	ShowWindow(hwnd, iCmdShow);
    	UpdateWindow(hwnd); //This function will generate a WM_PAINT message.        
    
    						/* The message loop for this program.
    						if received the WM_QUIT message, the function will return 0.*/
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return msg.wParam;
    
    }
    
    void PaintWindow(HWND hwnd, int iColor, int iFigure)
    {
    	static COLORREF crColor[8] = { RGB(0, 0,   0), RGB(0,   0, 255),
    		RGB(0, 255, 0), RGB(0, 255, 255),
    		RGB(255, 0,   0), RGB(255,   0, 255),
    		RGB(255, 255, 0), RGB(255, 255, 255) };
    	HBRUSH	hBrush;
    	HDC		hdc;
    	RECT	rect;
    
    	hdc = GetDC(hwnd);
    	GetClientRect(hwnd, &rect);
    	hBrush = CreateSolidBrush(crColor[iColor - IDC_BLACK]);
    	hBrush = (HBRUSH)SelectObject(hdc, hBrush);
    
    	if (iFigure == IDC_RECT)
    		Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
    	else
    		Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom);
    
    	DeleteObject(SelectObject(hdc, hBrush));
    	ReleaseDC(hwnd, hdc);
    }
    
    
    void PaintTheBlock(HWND hCtrl, int iColor, int iFigure)
    {
    	InvalidateRect(hCtrl, NULL, TRUE);
    	UpdateWindow(hCtrl);
    	PaintWindow(hCtrl, iColor, iFigure);
    }
    
    //define the Window Procedure WndProc        
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HINSTANCE hInstance;
    	PAINTSTRUCT		 ps;
    
    	switch (message) //get the message        
    	{
    	case WM_CREATE:
    		hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
    		return 0;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDM_APP_ABOUT:
    			if (DialogBox(hInstance, TEXT("AboutBox"), hwnd, AboutDlgProc))
    				InvalidateRect(hwnd, NULL, TRUE);
    			break;
    		}
    		break;
    
    	case WM_PAINT:
    		BeginPaint(hwnd, &ps);
    		EndPaint(hwnd, &ps);
    
    		PaintWindow(hwnd, iCurrentColor, iCurrentFigure);
    		return 0;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    	return  DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HWND	hCtrlBlock;
    	static int	iColor, iFigure;
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		iColor = iCurrentColor;
    		iFigure = iCurrentFigure;
    
    		CheckRadioButton(hDlg, IDC_BLACK, IDC_WHITE, iColor);
    		CheckRadioButton(hDlg, IDC_RECT, IDC_ELLIPSE, iFigure);
    
    		hCtrlBlock = GetDlgItem(hDlg, IDC_PAINT);
    
    		SetFocus(GetDlgItem(hDlg, iColor));
    		return FALSE;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDOK:
    			iCurrentColor = iColor;
    			iCurrentFigure = iFigure;
    			EndDialog(hDlg, TRUE);
    			return TRUE;
    
    		case IDCANCEL:
    			EndDialog(hDlg, FALSE);
    			return TRUE;
    
    		case IDC_BLACK:
    		case IDC_RED:
    		case IDC_GREEN:
    		case IDC_YELLOW:
    		case IDC_BLUE:
    		case IDC_MAGENTA:
    		case IDC_CYAN:
    		case IDC_WHITE:
    			iColor = LOWORD(wParam);
    			CheckRadioButton(hDlg, IDC_BLACK, IDC_WHITE, LOWORD(wParam)); //The LOWORD(wParam) is the current ID of the command.
    			PaintTheBlock(hCtrlBlock, iColor, iFigure);
    			return TRUE;
    
    		case IDC_RECT:
    		case IDC_ELLIPSE:
    			iFigure = LOWORD(wParam);
    			CheckRadioButton(hDlg, IDC_RECT, IDC_ELLIPSE, LOWORD(wParam));
    			PaintTheBlock(hCtrlBlock, iColor, iFigure);
    			return TRUE;
    		}
    		break;
    
    	case WM_PAINT:
    		PaintTheBlock(hCtrlBlock, iColor, iFigure);
    		break;
    	}
    
    	return FALSE;
    }

    About2.rc

    //Microsoft Developer Studio generated resource script.
    //
    #include "resource.h"
    
    #define APSTUDIO_READONLY_SYMBOLS
    /
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "afxres.h"
    
    /
    #undef APSTUDIO_READONLY_SYMBOLS
    
    /
    // English (U.S.) resources
    
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    #ifdef _WIN32
    LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
    #pragma code_page(1252)
    #endif //_WIN32
    
    #ifdef APSTUDIO_INVOKED
    /
    //
    // TEXTINCLUDE
    //
    
    1 TEXTINCLUDE DISCARDABLE 
    BEGIN
        "resource.h\0"
    END
    
    2 TEXTINCLUDE DISCARDABLE 
    BEGIN
        "#include ""afxres.h""\r\n"
        "\0"
    END
    
    3 TEXTINCLUDE DISCARDABLE 
    BEGIN
        "\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // Dialog
    //
    
    ABOUTBOX DIALOG DISCARDABLE  32, 32, 200, 234
    STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
    FONT 8, "MS Sans Serif"
    BEGIN
        ICON            "ABOUT2",IDC_STATIC,7,7,20,20
        CTEXT           "About2",IDC_STATIC,57,12,86,8
        CTEXT           "About Box Demo Program",IDC_STATIC,7,40,186,8
        LTEXT           "",IDC_PAINT,114,67,72,72
        GROUPBOX        "&Color",IDC_STATIC,7,60,84,143
        RADIOBUTTON     "&Black",IDC_BLACK,16,76,64,8,WS_GROUP | WS_TABSTOP
        RADIOBUTTON     "B&lue",IDC_BLUE,16,92,64,8
        RADIOBUTTON     "&Green",IDC_GREEN,16,108,64,8
        RADIOBUTTON     "Cya&n",IDC_CYAN,16,124,64,8
        RADIOBUTTON     "&Red",IDC_RED,16,140,64,8
        RADIOBUTTON     "&Magenta",IDC_MAGENTA,16,156,64,8
        RADIOBUTTON     "&Yellow",IDC_YELLOW,16,172,64,8
        RADIOBUTTON     "&White",IDC_WHITE,16,188,64,8
        GROUPBOX        "&Figure",IDC_STATIC,109,156,84,46,WS_GROUP
        RADIOBUTTON     "Rec&tangle",IDC_RECT,116,172,65,8,WS_GROUP | WS_TABSTOP
        RADIOBUTTON     "&Ellipse",IDC_ELLIPSE,116,188,64,8
        DEFPUSHBUTTON   "OK",IDOK,35,212,50,14,WS_GROUP
        PUSHBUTTON      "Cancel",IDCANCEL,113,212,50,14,WS_GROUP
    END
    
    
    /
    //
    // Icon
    //
    
    // Icon with lowest ID value placed first to ensure application icon
    // remains consistent on all systems.
    ABOUT2                  ICON    DISCARDABLE     "About2.ico"
    
    /
    //
    // Menu
    //
    
    ABOUT2 MENU DISCARDABLE 
    BEGIN
        POPUP "&Help"
        BEGIN
            MENUITEM "&About",                      IDM_APP_ABOUT
        END
    END
    
    
    /
    //
    // DESIGNINFO
    //
    
    #ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO DISCARDABLE 
    BEGIN
        "ABOUTBOX", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 193
            TOPMARGIN, 7
            BOTTOMMARGIN, 227
        END
    END
    #endif    // APSTUDIO_INVOKED
    
    #endif    // English (U.S.) resources
    /
    
    
    
    #ifndef APSTUDIO_INVOKED
    /
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    
    
    /
    #endif    // not APSTUDIO_INVOKED
    
    

    Resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Developer Studio generated include file.
    // Used by About2.rc
    //
    #define IDC_BLACK                       1000
    #define IDC_BLUE                        1001
    #define IDC_GREEN                       1002
    #define IDC_CYAN                        1003
    #define IDC_RED                         1004
    #define IDC_MAGENTA                     1005
    #define IDC_YELLOW                      1006
    #define IDC_WHITE                       1007
    #define IDC_RECT                        1008
    #define IDC_ELLIPSE                     1009
    #define IDC_PAINT                       1010
    #define IDM_APP_ABOUT                   40001
    
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        105
    #define _APS_NEXT_COMMAND_VALUE         40002
    #define _APS_NEXT_CONTROL_VALUE         1011
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif
    

    运行结果



    11.1.7 对话框控件的应用

    当一个单选按钮被鼠标按下或有焦点时按下空格,  子窗口像父窗口发送WM_COMMAND消息 LOWPRD(wParam) 是控件ID,高位是通知码

     lParam是控件的窗口句柄

    对于单选按钮通知码是 BN_CLICKED ,他等于0.  然后windows的对话框窗口过程把该消息发送给About2.c中的对话框过程。

    当对话框过程收到单选按钮的WM_COMMAND消息以后表明他被选中,斌给取消选中同组所有其他按钮


    CP9中  取消或选中单选需要发送一条BM_SETCHECK消息

    SendMessage(hwndCtrl, BM_SETCHECK, 1, 0);  选中

    SendMessage(hwndCtrl, BM_SETCHECK, 0, 0); 取消选中


    hwndCtrl = GetDlgItem(hDlg, id);

    id = GetWindowLong(hwndCtrl, GWL_ID);


    可以使用下面代码来选择和取消单选框。

    		case IDC_BLACK:
    		case IDC_RED:
    		case IDC_GREEN:
    		case IDC_YELLOW:
    		case IDC_BLUE:
    		case IDC_MAGENTA:
    		case IDC_CYAN:
    		case IDC_WHITE:
    			iColor = LOWORD(wParam);
    			for (i = IDC_BLACK; i <= IDC_WHITE; i++)
    			{
    				SendMessage(GetDlgItem(hDlg, i),
    					BM_SETCHECK, i == LOWORD(wParam), 0);
    			}

    另一种方法是 

    SendDlgItemMessage(hDlg, id, iMsg, wParam, lParam);

    等价于  SendMessage(GetDlgItem(hDlg, id), BM_SETCHECK, wParam, lParam);

    for (i = IDC_BLACK; i <= IDC_WHITE; i++)

    SendDlgMessage(hDlg, i,  BM_SETCHECK, i == LOWORD (wParam), lParam);


    或者使用

    CheckRadioButton(hDlg, idFirst, idLast, idCheck);


    对复选框也可以这样使用

    CheckDlgButton(hDlg, idCheckbox, iCheck);   1选择   0 取消

    iCheck = IsDlgButtonChecked(hDlg, idCheckbox);

    或者  SendMessage(hwndCtrl, BM_GETCHECK, 0, 0);


    在WM_COMMAND消息中切换状态

    CheckDlgButton(hDlg, idCheckbox, !IsDlgButtonChecked(hDlg, idCheckbox));


    如果是一个BS_AUTOCHECKBOX控件,则程序不需要处理WM_COMMAND消息  ,在对话框终止前使用IsDlgButtonChecked来获得按钮的选取状态。


    11.1.8  OK和Cancel按钮

    当用户按回车时,对话框窗口过程会产生一个WM_COMMAND消息,该消息的wParam参数的LOWORD会被设为默认的按钮的ID值,除非另一个按键有输入焦点。如果对话框没有按键是默认按钮。windows会像对话框过程发送一条LOWORD(wParam) 为IDOK的WM_COMMAND消息。   如果用户按下ESC或者Ctrl-Break, Windows会发送一条wParam参数为  LOWORD等于IDCANCEL的WM_COMMAND消息。

    EndDialog 第二个参数成为DialogBox函数的返回值


    11.1.9  避免全局变量


    定义一个数据结构和About对话框关联

    typedef struct

    {

        int iColor;

        int iFigure;

    }

    ABOUTBOX_DATA;


    在WndProc中   定义  static ABOUTBOX_DATA ad = { IDC_BLACK,  IDC_RECT}; 

    然后将iCurrentColor和iCurrentFigure替换为 ad.iColor  和  ad.iFigure

    当调用对话框使用DialogBoxParam


    if(DialogBoxParam(hInstance, TEXT("AboutBox"),

        hwnd, AboutDlgProc, &ad))


    最后一个参数将作为WM_INITDIALOG消息的lParam参数传递给对话框过程。

    对话框过程有两个基于ABOUTBOX_DATA结构的静态变量

    static ABOUTBOX_DATA ad, * pad;


    pad = (ABOUTBOX_DATA *) lParam;

    ad = * pad;

    在   Case IDOK

    * pad = ad;

    EndDialog(hDlg, TRUE);

    return TRUE;


    修改成非全局变量的版本

    #include <windows.h>  
    #include "resource.h"   
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.   
    BOOL	CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
    
    
    typedef struct
    {
    	int iColor;
    	int iFigure;
    }
    ABOUTBOX_DATA;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static      TCHAR szAppName[] = TEXT("About2");
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class        
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.        
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(hInstance, szAppName);// LoadIcon(NULL, IDI_APPLICATION);  
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndClass.lpszMenuName = szAppName;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.         
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	//This function will generate an WM_CREATE message.        
    	hwnd = CreateWindow(szAppName,      //Window class name        
    		TEXT("About Box Demo Program"),      //Window caption        
    		WS_OVERLAPPEDWINDOW,            //Window Style        
    		CW_USEDEFAULT,                  //initial x position        
    		CW_USEDEFAULT,                  //initial y position        
    		CW_USEDEFAULT,                  //initial x size        
    		CW_USEDEFAULT,                  //initial y size        
    		NULL,                           //parent window handle        
    		NULL,                           //window menu handle        
    		hInstance,                      //program instance handle        
    		NULL);                          //creation parameters        
    
    	ShowWindow(hwnd, iCmdShow);
    	UpdateWindow(hwnd); //This function will generate a WM_PAINT message.        
    
    						/* The message loop for this program.
    						if received the WM_QUIT message, the function will return 0.*/
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return msg.wParam;
    
    }
    
    void PaintWindow(HWND hwnd, int iColor, int iFigure)
    {
    	static COLORREF crColor[8] = { RGB(0, 0,   0), RGB(0,   0, 255),
    		RGB(0, 255, 0), RGB(0, 255, 255),
    		RGB(255, 0,   0), RGB(255,   0, 255),
    		RGB(255, 255, 0), RGB(255, 255, 255) };
    	HBRUSH	hBrush;
    	HDC		hdc;
    	RECT	rect;
    
    	hdc = GetDC(hwnd);
    	GetClientRect(hwnd, &rect);
    	hBrush = CreateSolidBrush(crColor[iColor - IDC_BLACK]);
    	hBrush = (HBRUSH)SelectObject(hdc, hBrush);
    
    	if (iFigure == IDC_RECT)
    		Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
    	else
    		Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom);
    
    	DeleteObject(SelectObject(hdc, hBrush));
    	ReleaseDC(hwnd, hdc);
    }
    
    
    void PaintTheBlock(HWND hCtrl, int iColor, int iFigure)
    {
    	InvalidateRect(hCtrl, NULL, TRUE);
    	UpdateWindow(hCtrl);
    	PaintWindow(hCtrl, iColor, iFigure);
    }
    
    //define the Window Procedure WndProc        
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HINSTANCE hInstance;
    	static ABOUTBOX_DATA ad = { IDC_BLACK,  IDC_RECT };
    	PAINTSTRUCT		 ps;
    
    	switch (message) //get the message        
    	{
    	case WM_CREATE:
    		hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
    		return 0;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDM_APP_ABOUT:
    			if (DialogBoxParam(hInstance, TEXT("AboutBox"), hwnd, AboutDlgProc, (LPARAM)(&ad)))
    				InvalidateRect(hwnd, NULL, TRUE);
    			break;
    		}
    		break;
    
    	case WM_PAINT:
    		BeginPaint(hwnd, &ps);
    		EndPaint(hwnd, &ps);
    
    		PaintWindow(hwnd, ad.iColor, ad.iFigure);
    		return 0;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    	return  DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HWND	hCtrlBlock;
    	static ABOUTBOX_DATA ad, *pad;
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		pad = (ABOUTBOX_DATA *)lParam;
    		ad = *pad;
    
    		CheckRadioButton(hDlg, IDC_BLACK, IDC_WHITE, ad.iColor);
    		CheckRadioButton(hDlg, IDC_RECT, IDC_ELLIPSE, ad.iFigure);
    
    		hCtrlBlock = GetDlgItem(hDlg, IDC_PAINT);
    
    		SetFocus(GetDlgItem(hDlg, ad.iColor));
    		return FALSE;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDOK:
    			*pad = ad;
    			EndDialog(hDlg, TRUE);
    			return TRUE;
    
    		case IDCANCEL:
    			EndDialog(hDlg, FALSE);
    			return TRUE;
    
    		case IDC_BLACK:
    		case IDC_RED:
    		case IDC_GREEN:
    		case IDC_YELLOW:
    		case IDC_BLUE:
    		case IDC_MAGENTA:
    		case IDC_CYAN:
    		case IDC_WHITE:
    			ad.iColor = LOWORD(wParam);
    			CheckRadioButton(hDlg, IDC_BLACK, IDC_WHITE, LOWORD(wParam)); //The LOWORD(wParam) is the current ID of the command.
    			PaintTheBlock(hCtrlBlock, ad.iColor, ad.iFigure);
    			return TRUE;
    
    		case IDC_RECT:
    		case IDC_ELLIPSE:
    			ad.iFigure = LOWORD(wParam);
    			CheckRadioButton(hDlg, IDC_RECT, IDC_ELLIPSE, LOWORD(wParam));
    			PaintTheBlock(hCtrlBlock, ad.iColor, ad.iFigure);
    			return TRUE;
    		}
    		break;
    
    	case WM_PAINT:
    		PaintTheBlock(hCtrlBlock, ad.iColor, ad.iFigure);
    		break;
    	}
    
    	return FALSE;
    }


    11.1.10 TAB停靠和选项组

    需要TAB访问的控件  加入 WS_TABSTOP

    不含TABSTOP样式的控件不应该获取输入焦点。 除非在WM_INITDIALOG 中强制设置焦点并返回FALSE, 否则windows会把输入焦点设置为对话框中第一个含有WS_TABSTOP格式的控件


    当焦点在单选按钮上时,添加WS_GROUP样式使得可以使用方向键来切换选择同一个GROUP中的其他单选。再下一个WS_GROUP之前的控件为一组


    &使得其后面的字母带下划线,同时增加了一个键盘接口。用户可以通过按下带有下划线的字母来将输入焦点移动到任何单选按钮。



    windows提供下列函数来查找下一个或前一个tab停靠位或者选项组

    hwndCtrl = GetNextDlgTabItem(hDlg, hwndCtrl, bPrevious);

    hwndCtrl= GetNextDlgGroupItem(hDlg, hwndCtrl, bPrevious);


    bPrevious是TRUE, 函数返回掐你个TAB停靠位或选项组;  如果是FALSE 返回下一个


    11.1.11 在对话框上绘图

    在对话框过程的WM_PAINT消息 或者切换图形时候调用

    PaintTheBlock(hCtrlBlock, iColor, iFigure);

    在WM_INITDIALOG消息时 

    hCtrlBlock = GetDlgItem(hDlg, IDC_PAINT);


    MapDialogRect 函数把对话框中的以字符为单位的坐标转换为客户区中以像素为单位的坐标。

    实际上是在子窗口控件上绘图。


    11.1.12 关于对话框的其他函数

    MoveWindow

    EnableWindow(hwndCtrl, bEnable);

    不要禁用含有输入焦点的控件


    11.1.13 定义程序自己的控件

    About3.cpp

    #include <windows.h>  
    #include "resource.h"   
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.   
    BOOL	CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK EllipPushWndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static      TCHAR szAppName[] = TEXT("About3");
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class        
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.        
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(hInstance, szAppName);// LoadIcon(NULL, IDI_APPLICATION);  
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndClass.lpszMenuName = szAppName;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.         
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = EllipPushWndProc;// assign the window procedure to windows class.        
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = NULL;// LoadIcon(NULL, IDI_APPLICATION);  
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    	wndClass.lpszMenuName = NULL;
    	wndClass.lpszClassName = TEXT("EllipPush");
    
    	RegisterClass(&wndClass);
    
    	//This function will generate an WM_CREATE message.        
    	hwnd = CreateWindow(szAppName,      //Window class name        
    		TEXT("About Box Demo Program"),      //Window caption        
    		WS_OVERLAPPEDWINDOW,            //Window Style        
    		CW_USEDEFAULT,                  //initial x position        
    		CW_USEDEFAULT,                  //initial y position        
    		CW_USEDEFAULT,                  //initial x size        
    		CW_USEDEFAULT,                  //initial y size        
    		NULL,                           //parent window handle        
    		NULL,                           //window menu handle        
    		hInstance,                      //program instance handle        
    		NULL);                          //creation parameters        
    
    	ShowWindow(hwnd, iCmdShow);
    	UpdateWindow(hwnd); //This function will generate a WM_PAINT message.        
    
    						/* The message loop for this program.
    						if received the WM_QUIT message, the function will return 0.*/
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return msg.wParam;
    
    }
    
    
    //define the Window Procedure WndProc        
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HINSTANCE hInstance;
    
    	switch (message) //get the message        
    	{
    	case WM_CREATE:
    		hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
    		return 0;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDM_APP_ABOUT:
    			DialogBox(hInstance, TEXT("AboutBox"), hwnd, AboutDlgProc);
    			return 0;
    		}
    		break;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    	return  DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		return TRUE;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDOK:
    			EndDialog(hDlg, TRUE);
    			return TRUE;
    		}
    		break;
    	}
    
    	return FALSE;
    }
    
    LRESULT CALLBACK EllipPushWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	TCHAR		szText[40];
    	HBRUSH		hBrush;
    	HDC			hdc;
    	PAINTSTRUCT	ps;
    	RECT		rect;
    
    	switch (message)
    	{
    	case WM_PAINT:
    		GetClientRect(hwnd, &rect);
    		GetWindowText(hwnd, szText, sizeof(szText));
    
    		hdc = BeginPaint(hwnd, &ps);
    
    		hBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
    		hBrush = (HBRUSH)SelectObject(hdc, hBrush);
    		SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
    		SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
    
    		Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom);
    		DrawText(hdc, szText, -1, &rect,
    			DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    
    		DeleteObject(SelectObject(hdc, hBrush));
    
    		EndPaint(hwnd, &ps);
    		return 0;
    
    	case WM_KEYUP:
    		if (wParam != VK_SPACE)
    			break;
    
    	case WM_LBUTTONUP:
    		SendMessage(GetParent(hwnd), WM_COMMAND, GetWindowLong(hwnd, GWL_ID),
    			(LPARAM)hwnd);
    		return 0;
    	}
    
    	return DefWindowProc(hwnd, message, wParam, lParam);
    }


    about3.rc

    //Microsoft Developer Studio generated resource script.
    //
    #include "resource.h"
    
    #define APSTUDIO_READONLY_SYMBOLS
    /
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "afxres.h"
    
    /
    #undef APSTUDIO_READONLY_SYMBOLS
    
    /
    // English (U.S.) resources
    
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    #ifdef _WIN32
    LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
    #pragma code_page(1252)
    #endif //_WIN32
    
    #ifdef APSTUDIO_INVOKED
    /
    //
    // TEXTINCLUDE
    //
    
    1 TEXTINCLUDE DISCARDABLE 
    BEGIN
        "resource.h\0"
    END
    
    2 TEXTINCLUDE DISCARDABLE 
    BEGIN
        "#include ""afxres.h""\r\n"
        "\0"
    END
    
    3 TEXTINCLUDE DISCARDABLE 
    BEGIN
        "\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // Dialog
    //
    
    ABOUTBOX DIALOG DISCARDABLE  32, 32, 180, 100
    STYLE DS_MODALFRAME | WS_POPUP
    FONT 8, "MS Sans Serif"
    BEGIN
        CONTROL         "OK",IDOK,"EllipPush",WS_GROUP | WS_TABSTOP,73,79,32,14
        ICON            "ABOUT3",IDC_STATIC,7,7,20,20
        CTEXT           "About3",IDC_STATIC,40,12,100,8
        CTEXT           "About Box Demo Program",IDC_STATIC,7,40,166,8
        CTEXT           "(c) Charles Petzold, 1998",IDC_STATIC,7,52,166,8
    END
    
    
    /
    //
    // Menu
    //
    
    ABOUT3 MENU DISCARDABLE 
    BEGIN
        POPUP "&Help"
        BEGIN
            MENUITEM "&About About3...",            IDM_APP_ABOUT
        END
    END
    
    
    /
    //
    // DESIGNINFO
    //
    
    #ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO DISCARDABLE 
    BEGIN
        "ABOUTBOX", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 173
            TOPMARGIN, 7
            BOTTOMMARGIN, 93
        END
    END
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // Icon
    //
    
    // Icon with lowest ID value placed first to ensure application icon
    // remains consistent on all systems.
    ABOUT3                  ICON    DISCARDABLE     "icon1.ico"
    #endif    // English (U.S.) resources
    /
    
    
    
    #ifndef APSTUDIO_INVOKED
    /
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    
    
    /
    #endif    // not APSTUDIO_INVOKED
    
    

    resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Developer Studio generated include file.
    // Used by About3.rc
    //
    #define IDM_APP_ABOUT                   40001
    #define IDC_STATIC                      -1
    
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        105
    #define _APS_NEXT_COMMAND_VALUE         40002
    #define _APS_NEXT_CONTROL_VALUE         1001
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif
    


    运行结果


    11.2 非模态对话框

    hDlgModeless = CreateDialog(hInstance, szTemplate, hwndParent, DialogProc); //创建非模态对话框


    11.2.1 模态与非模态对话框的区别

    1.非模态对话框通常包含 标题栏和系统菜单栏

    STYLE  WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE

    而模态通常不需要。

    2. 通常非模态对话框包含WS_VISIBLE样式 ,否则需要在CreateDialog以后调用ShowWindow显示

    hDlgModeless = CraeteDialog(...);

    ShowWindow (hDlgModeless, SW_SHOW);


    3. 非模态对话框的消息要进入你程序的消息队列。而消息队列必须经过改动才能把这些消息传递给对话框窗口过程。

    hDlgModeless = CreateDialog(...);


    修改消息循环

    while (GetMessage(&msg, NULL, 0, 0))
    {
    	if (hDlgModeless == 0 || !IsDialogMessage(hDlgModeless, &msg))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    }
    如果消息是针对对话框的,IsDialogMessage就会把消息发送给对话框的窗口过程并返回TRUE,否则返回FALSE

    如果应用程序使用了键盘加速键,修改以后的消息循环如下

    while (GetMessage(&msg, NULL, 0, 0))
    {
    	if (hDlgModeless == 0 || !IsDialogMessage(hDlgModeless, &msg))
    	{
    		if (!TranslateAccelerator(HWND, hAccel, &msg))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}	
    	}
    }
    在创建非模态对话框之前hDlgModeless保持为0 ,在销毁以后也至于0


    4. 使用Destroywindow 来结束非模态对话框。当调用DestroyWindow时,还要把hDlgModeless全局变量设置为NULL.

    在非模态对话框的对话框过程中处理WM_CLOSE消息

    case WM_CLOSE:

         DestroyWindow(hDlg);

          hDlgModeless = NULL;

          break;

    避免使用全局变量可以使用CreateDialogParam来创建费莫泰对话框,并给他传递一个指向结构的指针。


    11.2.2 新的COLORS程序

    color2.cpp

    #include <windows.h>      
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.    
    BOOL CALLBACK ColorScrDlg(HWND, UINT, WPARAM, LPARAM);
    
    HWND hDlgModeless;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static      TCHAR szAppName[] = TEXT("Colors2");
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class      
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.      
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = CreateSolidBrush(0L);//(HBRUSH)GetStockObject(WHITE_BRUSH);  
    	wndClass.lpszMenuName = NULL;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.       
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	//This function will generate an WM_CREATE message.      
    	hwnd = CreateWindow(szAppName,      //Window class name      
    		TEXT("Color Scroll"),      //Window caption      
    		WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,            //Window Style      
    		CW_USEDEFAULT,                  //initial x position      
    		CW_USEDEFAULT,                  //initial y position      
    		CW_USEDEFAULT,                  //initial x size      
    		CW_USEDEFAULT,                  //initial y size      
    		NULL,                           //parent window handle      
    		NULL,                           //window menu handle      
    		hInstance,                      //program instance handle      
    		NULL);                          //creation parameters      
    
    	ShowWindow(hwnd, iCmdShow);
    	UpdateWindow(hwnd); //This function will generate a WM_PAINT message.   
    
    	hDlgModeless = CreateDialog(hInstance, TEXT("ColorScrDlg"),
    								hwnd, ColorScrDlg);
    
    						/* The message loop for this program.
    						if received the WM_QUIT message, the function will return 0.*/
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		if (hDlgModeless == 0 || !IsDialogMessage(hDlgModeless, &msg))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    	}
    	return msg.wParam;
    
    }
    
    //define the Window Procedure WndProc      
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message) //get the message      
    	{
    	case WM_DESTROY:
    		DeleteObject((HGDIOBJ)SetClassLong(hwnd, GCL_HBRBACKGROUND,
    			(LONG)GetStockObject(WHITE_BRUSH)));
    		PostQuitMessage(0);
    		return 0;
    	}
    	return  DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    BOOL CALLBACK ColorScrDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static int		iColor[3];
    	HWND			hwndParent, hCtrl;
    	int				iCtrlID, iIndex;
    
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		for (iCtrlID = 10; iCtrlID < 13; iCtrlID++)
    		{
    			hCtrl = GetDlgItem(hDlg, iCtrlID);
    			SetScrollRange(hCtrl, SB_CTL, 0, 255, FALSE);
    			SetScrollPos(hCtrl, SB_CTL, 0, FALSE);
    		}
    		return TRUE;
    
    	case WM_VSCROLL:
    		hCtrl = (HWND)lParam;
    		iCtrlID = GetWindowLong(hCtrl, GWL_ID);
    		iIndex = iCtrlID - 10;
    		hwndParent = GetParent(hDlg);
    
    		switch (LOWORD(wParam))
    		{
    		case SB_PAGEDOWN:
    			iColor[iIndex] += 15;	//fall through
    		case SB_LINEDOWN:
    			iColor[iIndex] = min(255, iColor[iIndex] + 1);
    			break;
    		case SB_PAGEUP:
    			iColor[iIndex] -= 15;	//fall through
    		case SB_LINEUP:
    			iColor[iIndex] = max(0, iColor[iIndex] - 1);
    			break;
    		case SB_TOP:
    			iColor[iIndex] = 0;
    			break;
    		case SB_BOTTOM:
    			iColor[iIndex] = 255;
    			break;
    		case SB_THUMBPOSITION:
    		case SB_THUMBTRACK:
    			iColor[iIndex] = HIWORD(wParam);
    			break;
    		default:
    			return FALSE;
    		}
    		SetScrollPos(hCtrl, SB_CTL, iColor[iIndex], TRUE);
    		SetDlgItemInt(hDlg, iCtrlID + 3, iColor[iIndex], FALSE);
    
    		DeleteObject((HGDIOBJ)SetClassLong(hwndParent, GCL_HBRBACKGROUND,
    			(LONG)CreateSolidBrush(
    				RGB(iColor[0], iColor[1], iColor[2]))));
    
    		InvalidateRect(hwndParent, NULL, TRUE);
    		return TRUE;
    	case WM_CLOSE:
    		DestroyWindow(hDlg);
    		hDlgModeless = NULL;
    		break;
    	}
    	return FALSE;
    }

    colors2.rc

    // Microsoft Visual C++ generated resource script.
    //
    #include "resource.h"
    
    #define APSTUDIO_READONLY_SYMBOLS
    /
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "afxres.h"
    
    /
    #undef APSTUDIO_READONLY_SYMBOLS
    
    /
    // English (United States) resources
    
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
    #pragma code_page(1252)
    
    #ifdef APSTUDIO_INVOKED
    /
    //
    // TEXTINCLUDE
    //
    
    1 TEXTINCLUDE 
    BEGIN
        "resource.h\0"
    END
    
    2 TEXTINCLUDE 
    BEGIN
        "#include ""afxres.h""\r\n"
        "\0"
    END
    
    3 TEXTINCLUDE 
    BEGIN
        "\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // Dialog
    //
    
    COLORSCRDLG DIALOGEX 16, 16, 120, 141
    STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
    CAPTION "Color Scroll Scrollbars"
    FONT 8, "MS Sans Serif", 0, 0, 0x0
    BEGIN
        CTEXT           "&Red",IDC_STATIC,8,8,24,8,NOT WS_GROUP
        SCROLLBAR       10,8,20,24,100,SBS_VERT | WS_TABSTOP
        CTEXT           "0",13,8,124,24,8,NOT WS_GROUP
        CTEXT           "&Green",IDC_STATIC,48,8,24,8,NOT WS_GROUP
        SCROLLBAR       11,48,20,24,100,SBS_VERT | WS_TABSTOP
        CTEXT           "0",14,48,124,24,8,NOT WS_GROUP
        CTEXT           "&Blue",IDC_STATIC,89,8,24,8,NOT WS_GROUP
        SCROLLBAR       12,89,20,24,100,SBS_VERT | WS_TABSTOP
        CTEXT           "0",15,89,124,24,8,NOT WS_GROUP
    END
    
    
    /
    //
    // DESIGNINFO
    //
    
    #ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO
    BEGIN
        "COLORSCRDLG", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 113
            TOPMARGIN, 7
            BOTTOMMARGIN, 134
        END
    END
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // AFX_DIALOG_LAYOUT
    //
    
    COLORSCRDLG AFX_DIALOG_LAYOUT
    BEGIN
        0
    END
    
    #endif    // English (United States) resources
    /
    
    
    
    #ifndef APSTUDIO_INVOKED
    /
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    
    
    /
    #endif    // not APSTUDIO_INVOKED
    
    

    resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Developer Studio generated include file.
    // Used by Colors2.rc
    //
    #define IDC_STATIC                      -1
    
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        102
    #define _APS_NEXT_COMMAND_VALUE         40001
    #define _APS_NEXT_CONTROL_VALUE         1003
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif
    

    运行结果



    11.2.3 HEXCALC:窗口还是对话框?

    hexcalc.cpp

    #include <windows.h>      
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.    
    
    HWND hDlgModeless;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static      TCHAR szAppName[] = TEXT("HexCalc");
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class      
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.      
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = DLGWINDOWEXTRA;		// Note!
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(NULL, szAppName);
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);//(HBRUSH)GetStockObject(WHITE_BRUSH);  
    	wndClass.lpszMenuName = NULL;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.       
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	hwnd = CreateDialog(hInstance, szAppName, 0, NULL);
    
    	ShowWindow(hwnd, iCmdShow);
    
    	/* The message loop for this program.
    	if received the WM_QUIT message, the function will return 0.*/
    	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;
    	}
    }
    
    //define the Window Procedure WndProc      
    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) //get the message      
    	{
    	case WM_KEYDOWN:
    		if (wParam != VK_LEFT)			//left arrow --> backspace
    			break;
    		wParam = VK_BACK;
    
    		// fall through
    
    	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));
    			bNewNumber = TRUE;
    			iOperation = LOWORD(wParam);
    		}
    
    		return 0;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    	return  DefWindowProc(hwnd, message, wParam, lParam);
    }

    hexcalc.rc

    //Microsoft Developer Studio generated resource script.
    //
    #include "resource.h"
    
    #define APSTUDIO_READONLY_SYMBOLS
    /
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "afxres.h"
    
    /
    #undef APSTUDIO_READONLY_SYMBOLS
    
    /
    // English (U.S.) resources
    
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    #ifdef _WIN32
    LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
    #pragma code_page(1252)
    #endif //_WIN32
    
    #ifdef APSTUDIO_INVOKED
    /
    //
    // TEXTINCLUDE
    //
    
    1 TEXTINCLUDE DISCARDABLE 
    BEGIN
        "resource.h\0"
    END
    
    2 TEXTINCLUDE DISCARDABLE 
    BEGIN
        "#include ""afxres.h""\r\n"
        "\0"
    END
    
    3 TEXTINCLUDE DISCARDABLE 
    BEGIN
        "#include ""hexcalc.dlg""\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // Icon
    //
    
    // Icon with lowest ID value placed first to ensure application icon
    // remains consistent on all systems.
    HEXCALC                 ICON    DISCARDABLE     "HexCalc.ico"
    #endif    // English (U.S.) resources
    /
    
    
    
    #ifndef APSTUDIO_INVOKED
    /
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    #include "hexcalc.dlg"
    
    /
    #endif    // not APSTUDIO_INVOKED
    
    

    hexcalc.dlg

    /*---------------------------
       HEXCALC.DLG dialog script
      ---------------------------*/
    
    HexCalc DIALOG -1, -1, 102, 122
    STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
    CLASS "HexCalc"
    CAPTION "Hex Calculator"
    {
         PUSHBUTTON "D",       68,  8,  24, 14, 14
         PUSHBUTTON "A",       65,  8,  40, 14, 14
         PUSHBUTTON "7",       55,  8,  56, 14, 14
         PUSHBUTTON "4",       52,  8,  72, 14, 14
         PUSHBUTTON "1",       49,  8,  88, 14, 14
         PUSHBUTTON "0",       48,  8, 104, 14, 14
         PUSHBUTTON "0",       27, 26,   4, 50, 14
         PUSHBUTTON "E",       69, 26,  24, 14, 14
         PUSHBUTTON "B",       66, 26,  40, 14, 14
         PUSHBUTTON "8",       56, 26,  56, 14, 14
         PUSHBUTTON "5",       53, 26,  72, 14, 14
         PUSHBUTTON "2",       50, 26,  88, 14, 14
         PUSHBUTTON "Back",     8, 26, 104, 32, 14
         PUSHBUTTON "C",       67, 44,  40, 14, 14
         PUSHBUTTON "F",       70, 44,  24, 14, 14
         PUSHBUTTON "9",       57, 44,  56, 14, 14
         PUSHBUTTON "6",       54, 44,  72, 14, 14
         PUSHBUTTON "3",       51, 44,  88, 14, 14
         PUSHBUTTON "+",       43, 62,  24, 14, 14
         PUSHBUTTON "-",       45, 62,  40, 14, 14
         PUSHBUTTON "*",       42, 62,  56, 14, 14
         PUSHBUTTON "/",       47, 62,  72, 14, 14
         PUSHBUTTON "%",       37, 62,  88, 14, 14
         PUSHBUTTON "Equals",  61, 62, 104, 32, 14
         PUSHBUTTON "&&",      38, 80,  24, 14, 14
         PUSHBUTTON "|",      124, 80,  40, 14, 14
         PUSHBUTTON "^",       94, 80,  56, 14, 14
         PUSHBUTTON "<",       60, 80,  72, 14, 14
         PUSHBUTTON ">",       62, 80,  88, 14, 14
    }
    

    resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Developer Studio generated include file.
    // Used by HexCalc.rc
    //
    
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        103
    #define _APS_NEXT_COMMAND_VALUE         40001
    #define _APS_NEXT_CONTROL_VALUE         1003
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif
    


    运行结果


    11.3 公用对话框

    打开,存储文件,查找和替换,选择颜色字体的对话框。

    创建某一结构并传递给公用对话框的某一函数,就能够显示公用对话框。


    11.3.1 完善POPPAD


    该项目的加入内存泄漏检测 ,加入设置zi

    poppad3.cpp


    popfile.cpp


    #include <windows.h>
    #include <commdlg.h>
    #include "resource.h"
    #include "DetectMemoryLeak.h"
    
    #define EDITID 1 
    #define UNTITLED TEXT("(untitled)")
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure. 
    BOOL	CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
    
    // Functions in POPFILE.cpp
    void PopFileInitialize(HWND);
    BOOL PopFileOpenDlg(HWND, PTSTR, PTSTR);
    BOOL PopFileSaveDlg(HWND, PTSTR, PTSTR);
    BOOL PopFileRead(HWND, PTSTR);
    BOOL PopFileWrite(HWND, PTSTR);
    
    // Function in POPFIND.cpp
    
    HWND PopFindFindDlg(HWND);
    HWND PopFindReplaceDlg(HWND);
    BOOL PopFindFindText(HWND, int *, LPFINDREPLACE);
    BOOL PopFindReplaceText(HWND, int *, LPFINDREPLACE);
    BOOL PopFindNextText(HWND, int *);
    BOOL PopFindValidFind(void);
    
    // Functions in POPFONT.c
    
    void PopFontInitialize(HWND);
    BOOL PopFontChooseFont(HWND);
    void PopFontSetFont(HWND);
    void PopFontDeinitialize(void);
    BOOL PopFontChooseFontColor(HWND);
    void PopFontSetFontColor(HWND, COLORREF *);
    
    
    // Functions in POPPRINT.c
    
    BOOL PopPrntPrintFile(HINSTANCE, HWND, HWND, PTSTR);
    
    // Global variables
    // These variable could only be accessed in poppad3.cpp
    static HWND hDlgModeless;
    static TCHAR szAppName[] = TEXT("PopPad");
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    	HACCEL		hAccel;
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class      
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.      
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(hInstance, szAppName);// LoadIcon(NULL, IDI_APPLICATION);
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndClass.lpszMenuName = szAppName;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.       
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	//This function will generate an WM_CREATE message.      
    	hwnd = CreateWindow(szAppName,      //Window class name      
    		NULL,      //Window caption      
    		WS_OVERLAPPEDWINDOW,            //Window Style      
    		CW_USEDEFAULT,                  //initial x position      
    		CW_USEDEFAULT,                  //initial y position      
    		CW_USEDEFAULT,                  //initial x size      
    		CW_USEDEFAULT,				    //initial y size      
    		NULL,                           //parent window handle      
    		NULL,                           //window menu handle      
    		hInstance,                      //program instance handle      
    		NULL);                          //creation parameters      
    
    	ShowWindow(hwnd, iCmdShow);
    	UpdateWindow(hwnd); //This function will generate a WM_PAINT message.      
    
    	hAccel = LoadAccelerators(hInstance, szAppName);
    
    	/* The message loop for this program.
    	if received the WM_QUIT message, the function will return 0.*/
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		if (hDlgModeless == NULL || !IsDialogMessage(hDlgModeless, &msg))
    		{
    			if (!TranslateAccelerator(hwnd, hAccel, &msg))
    			{
    				TranslateMessage(&msg);
    				DispatchMessage(&msg);
    			}
    		}
    	}
    	return msg.wParam;
    }
    
    void DoCaption(HWND hwnd, TCHAR * szTitleName)
    {
    	TCHAR szCaption[64 + MAX_PATH];
    
    	wsprintf(szCaption, TEXT("%s - %s"), szAppName,
    		szTitleName[0] ? szTitleName : UNTITLED);
    
    	SetWindowText(hwnd, szCaption);
    }
    
    void OkMessage(HWND hwnd, TCHAR * szMessage, TCHAR * szTitleName)
    {
    	TCHAR szBuffer[64 + MAX_PATH];
    
    	wsprintf(szBuffer, szMessage, szTitleName[0] ? szTitleName : UNTITLED);
    
    	MessageBox(hwnd, szBuffer, szAppName, MB_OK | MB_ICONEXCLAMATION);
    }
    
    short AskAboutSave(HWND hwnd, TCHAR * szTitleName)
    {
    	TCHAR szBuffer[64 + MAX_PATH];
    	int iReturn;
    
    	wsprintf(szBuffer, TEXT("Save current changes in %s?"),
    		szTitleName[0] ? szTitleName : UNTITLED);
    
    	iReturn = MessageBox(hwnd, szBuffer, szAppName,
    		MB_YESNOCANCEL | MB_ICONQUESTION);
    
    	if (iReturn == IDYES)
    		if (!SendMessage(hwnd, WM_COMMAND, IDM_FILE_SAVE, 0))
    			iReturn = IDCANCEL;
    
    	return iReturn;
    }
    
    //define the Window Procedure WndProc      
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static BOOL bNeedSave = FALSE;
    	static HINSTANCE hInst;
    	static HWND hwndEdit;
    	static int iOffset;
    	static TCHAR szFileName[MAX_PATH], szTitleName[MAX_PATH];
    	static UINT messageFindReplace;
    	int iSelBeg, iSelEnd, iEnable;
    	static COLORREF iColor;
    	static HBRUSH hBrushEdit;
    	LPFINDREPLACE pfr;
    
    	switch (message) //get the message      
    	{
    	case WM_CREATE:
    		hInst = ((LPCREATESTRUCT)lParam)->hInstance;
    
    		hwndEdit = CreateWindow(TEXT("edit"), NULL,
    			WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
    			WS_BORDER | ES_LEFT | ES_MULTILINE |
    			ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
    			0, 0, 0, 0,
    			hwnd, (HMENU)EDITID,
    			hInst, NULL);
    
    		SendMessage(hwndEdit, EM_LIMITTEXT, 3200, 0L);
    
    		// Initialize common dialog box stuff
    
    		PopFileInitialize(hwnd);
    		PopFontInitialize(hwndEdit);
    
    		messageFindReplace = RegisterWindowMessage(FINDMSGSTRING);
    
    		DoCaption(hwnd, szTitleName);
    
    		hBrushEdit = CreateSolidBrush(GetSysColor(COLOR_BTNHILIGHT));
    
    		return 0;
    
    	case WM_SETFOCUS:
    		SetFocus(hwndEdit);
    		return 0;
    
    	case WM_SIZE:
    		MoveWindow(hwndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
    		return 0;
    
    	case WM_INITMENUPOPUP:
    		switch (lParam)
    		{
    		case 1:			// The index of edit menu
    						// Enable Undo if edit control can do it.
    
    			EnableMenuItem((HMENU)wParam, IDM_EDIT_UNDO,
    				SendMessage(hwndEdit, EM_CANUNDO, 0, 0) ?
    				MF_ENABLED : MF_GRAYED);
    
    			// Enable Paste if text is in the clipboard
    
    			EnableMenuItem((HMENU)wParam, IDM_EDIT_PASTE,
    				IsClipboardFormatAvailable(CF_TEXT) ?
    				MF_ENABLED : MF_GRAYED);
    
    			// Enable Cut, Copy, and Del if text is selected.
    
    			SendMessage(hwndEdit, EM_GETSEL, (WPARAM)&iSelBeg, (LPARAM)&iSelEnd);
    
    			iEnable = iSelBeg != iSelEnd ? MF_ENABLED : MF_GRAYED;
    
    			EnableMenuItem((HMENU)wParam, IDM_EDIT_CUT, iEnable);
    			EnableMenuItem((HMENU)wParam, IDM_EDIT_COPY, iEnable);
    			EnableMenuItem((HMENU)wParam, IDM_EDIT_CLEAR, iEnable);
    			break;
    
    		case 2:				// Search menu
    
    							// Enable Find, Next, and Replace if modeless
    							// dialogs are not already active
    
    			iEnable = hDlgModeless == NULL ?
    				MF_ENABLED : MF_GRAYED;
    
    			EnableMenuItem((HMENU)wParam, IDM_SEARCH_FIND, iEnable);
    			EnableMenuItem((HMENU)wParam, IDM_SEARCH_NEXT, iEnable);
    			EnableMenuItem((HMENU)wParam, IDM_SEARCH_REPLACE, iEnable);
    			break;
    		}
    		return 0;
    	case WM_CTLCOLOREDIT:
    		if (EDITID == GetWindowLong((HWND)lParam, GWL_ID))
    		{
    			SetTextColor((HDC)wParam, iColor);
    			SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNHIGHLIGHT));
    			return (LRESULT)hBrushEdit;
    		}
    		break;
    	case WM_COMMAND:
    		if (lParam && LOWORD(wParam) == EDITID) //edit control command.
    		{
    			switch (HIWORD(wParam))
    			{
    			case EN_UPDATE:
    				bNeedSave = TRUE;
    				return 0;
    
    			case EN_ERRSPACE:
    			case EN_MAXTEXT:
    				MessageBox(hwnd, TEXT("Edit control out of space."),
    					szAppName, MB_OK | MB_ICONSTOP);
    				return 0;
    
    			case EM_SETSEL:
    				return 0;
    			}
    			break;
    		}
    
    		switch (LOWORD(wParam))
    		{
    			// Messages from File menu
    		case IDM_FILE_NEW:
    			if (bNeedSave && IDCANCEL == AskAboutSave(hwnd, szTitleName))
    				return 0;
    
    			SetWindowText(hwndEdit, TEXT("\0"));
    			szFileName[0] = TEXT('\0');
    			szTitleName[0] = TEXT('\0');
    			DoCaption(hwnd, szTitleName);
    			bNeedSave = FALSE;
    			return 0;
    
    		case IDM_FILE_OPEN:
    			if (bNeedSave && IDCANCEL == AskAboutSave(hwnd, szTitleName))
    				return 0;
    
    			if (PopFileOpenDlg(hwnd, szFileName, szTitleName))
    			{
    				if (!PopFileRead(hwndEdit, szFileName))
    				{
    					OkMessage(hwnd, TEXT("Could not read file %s!"),
    						szTitleName);
    					szFileName[0] = TEXT('\0');
    					szTitleName[0] = TEXT('\0');
    				}
    			}
    
    			DoCaption(hwnd, szTitleName);
    			bNeedSave = FALSE;
    			return 0;
    
    		case IDM_FILE_SAVE:
    			if (szFileName[0])
    			{
    				if (PopFileWrite(hwndEdit, szFileName))
    				{
    					bNeedSave = FALSE;
    					return 1;
    				}
    				else
    				{
    					OkMessage(hwnd, TEXT("Could not write file %s"),
    						szTitleName);
    
    					return 0;
    				}
    			}
    
    			// fall through
    
    		case IDM_FILE_SAVE_AS:
    			if (PopFileSaveDlg(hwnd, szFileName, szTitleName))
    			{
    				DoCaption(hwnd, szTitleName);
    
    				if (PopFileWrite(hwndEdit, szFileName))
    				{
    					bNeedSave = FALSE;
    					return 1;
    				}
    				else
    				{
    					OkMessage(hwnd, TEXT("Could not write file %s"),
    						szTitleName);
    					return 0;
    				}
    			}
    			return 0;
    
    		case IDM_FILE_PRINT:
    			if (!PopPrntPrintFile(hInst, hwnd, hwndEdit, szTitleName))
    				OkMessage(hwnd, TEXT("Could not print file %s"), szTitleName);
    			return 0;
    
    		case IDM_APP_EXIT:
    			SendMessage(hwnd, WM_CLOSE, 0, 0);
    			return 0;
    
    			// Messages from Edit menu
    		case IDM_EDIT_UNDO:
    			SendMessage(hwndEdit, WM_UNDO, 0, 0);
    			return 0;
    
    		case IDM_EDIT_CUT:
    			SendMessage(hwndEdit, WM_CUT, 0, 0);
    			return 0;
    
    		case IDM_EDIT_COPY:
    			SendMessage(hwndEdit, WM_COPY, 0, 0);
    			return 0;
    
    		case IDM_EDIT_PASTE:
    			SendMessage(hwndEdit, WM_PASTE, 0, 0);
    			return 0;
    
    		case IDM_EDIT_CLEAR:
    			SendMessage(hwndEdit, WM_CLEAR, 0, 0);
    			return 0;
    
    		case IDM_EDIT_SELECT_ALL:
    			SendMessage(hwndEdit, EM_SETSEL, 0, -1);
    			return 0;
    
    			// Messages from Search menu
    
    		case IDM_SEARCH_FIND:
    			SendMessage(hwndEdit, EM_GETSEL, 0, (LPARAM)&iOffset);
    			hDlgModeless = PopFindFindDlg(hwnd);
    			return 0;
    
    		case IDM_SEARCH_NEXT:
    			SendMessage(hwndEdit, EM_GETSEL, 0, (LPARAM)&iOffset);
    
    			if (PopFindValidFind())
    				PopFindNextText(hwndEdit, &iOffset);
    			else
    				hDlgModeless = PopFindFindDlg(hwnd);
    
    			return 0;
    
    		case IDM_SEARCH_REPLACE:
    			SendMessage(hwndEdit, EM_GETSEL, 0, (LPARAM)&iOffset);
    			hDlgModeless = PopFindReplaceDlg(hwnd);
    			return 0;
    
    		case IDM_FORMAT_FONT:
    			if (PopFontChooseFont(hwnd))
    				PopFontSetFont(hwndEdit);
    
    			return 0;
    
    		case IDM_FORMAT_COLOR:
    			if (PopFontChooseFontColor((hwnd)))
    				PopFontSetFontColor(hwndEdit, &iColor);
    			return 0;
    
    			// Messages from Help menu
    		case IDM_HELP:
    			OkMessage(hwnd, TEXT("Help not yet implemented!"),
    				TEXT("\0"));
    			return 0;
    
    		case IDM_APP_ABOUT:
    			DialogBox(hInst, TEXT("AboutBox"), hwnd, AboutDlgProc);
    			return 0;
    
    		}
    		break;
    
    	case WM_CLOSE:
    		if (!bNeedSave || IDCANCEL != AskAboutSave(hwnd, szTitleName))
    			DestroyWindow(hwnd);
    		return 0;
    
    	case WM_QUERYENDSESSION:
    		if (!bNeedSave || IDCANCEL != AskAboutSave(hwnd, szTitleName))
    			return 1;
    
    		return 0;
    
    	case WM_DESTROY:
    		DeleteObject(hBrushEdit);
    		PopFontDeinitialize();
    		PostQuitMessage(0);
    		return 0;
    
    	default:
    		// Process "Find-Replace" messages
    
    		if (message == messageFindReplace)
    		{
    			pfr = (LPFINDREPLACE)lParam;
    
    			if (pfr->Flags & FR_DIALOGTERM)
    				hDlgModeless = NULL;
    
    			if (pfr->Flags & FR_FINDNEXT)
    				if (!PopFindFindText(hwndEdit, &iOffset, pfr))
    					OkMessage(hwnd, TEXT("Text not found!"),
    						TEXT("\0"));
    
    			if (pfr->Flags & FR_REPLACE || pfr->Flags & FR_REPLACEALL)
    				if (!PopFindReplaceText(hwndEdit, &iOffset, pfr))
    					OkMessage(hwnd, TEXT("Text not found!"),
    						TEXT("\0"));
    
    			if (pfr->Flags & FR_REPLACEALL)
    				while (PopFindReplaceText(hwndEdit, &iOffset, pfr))
    					;
    			return 0;
    		}
    		break;
    	 }
    	return  DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		return TRUE;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDOK:
    			EndDialog(hDlg, 0);
    			return TRUE;
    		}
    		break;
    	}
    
    	return FALSE;
    }


    popfind.cpp

    #include <windows.h>
    #include <commdlg.h>
    #include <tchar.h>			// for _tcsstr (strstr for Unicode & non-unicode)
    #include "DetectMemoryLeak.h"
    
    #define MAX_STRING_LEN	256
    
    static TCHAR szFindText[MAX_STRING_LEN];
    static TCHAR szReplText[MAX_STRING_LEN];
    
    HWND PopFindFindDlg(HWND hwnd)
    {
    	static FINDREPLACE fr;		// must be static for modeless dialog!!!
    
    	fr.lStructSize = sizeof(FINDREPLACE);
    	fr.hwndOwner = hwnd;
    	fr.hInstance = NULL;
    	fr.Flags = FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD;
    	fr.lpstrFindWhat = szFindText;
    	fr.lpstrReplaceWith = NULL;
    	fr.wFindWhatLen = MAX_STRING_LEN;
    	fr.wReplaceWithLen = 0;
    	fr.lCustData = 0;
    	fr.lpfnHook = NULL;
    	fr.lpTemplateName = NULL;
    
    	return FindText(&fr);
    }
    
    HWND PopFindReplaceDlg(HWND hwnd)
    {
    	static FINDREPLACE fr;		// must be static for modeless dialog!!!
    
    	fr.lStructSize = sizeof(FINDREPLACE);
    	fr.hwndOwner = hwnd;
    	fr.hInstance = NULL;
    	fr.Flags = FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD;
    	fr.lpstrFindWhat = szFindText;
    	fr.lpstrReplaceWith = szReplText;
    	fr.wFindWhatLen = MAX_STRING_LEN;
    	fr.wReplaceWithLen = MAX_STRING_LEN;
    	fr.lCustData = 0;
    	fr.lpfnHook = NULL;
    	fr.lpTemplateName = NULL;
    
    	return ReplaceText(&fr);
    }
    
    BOOL PopFindFindText(HWND hwndEdit, int * piSearchOffset, LPFINDREPLACE pfr)
    {
    	int iLength, iPos;
    	PTSTR pstrDoc, pstrPos;
    
    	// Read in the edit document
    
    	iLength = GetWindowTextLength(hwndEdit);
    
    	if (NULL == (pstrDoc = (PTSTR)malloc((iLength + 1) * sizeof(TCHAR))))
    		return FALSE;
    
    	GetWindowText(hwndEdit, pstrDoc, iLength + 1);
    
    	// Search the document for the find string
    
    	pstrPos = _tcsstr(pstrDoc + *piSearchOffset, pfr->lpstrFindWhat);
    	free(pstrDoc);
    
    	// Return an error code if the string cannot be found
    
    	if (pstrPos == NULL)
    		return FALSE;
    
    	// Find the position in the document and the new start offset
    
    	iPos = pstrPos - pstrDoc;
    	*piSearchOffset = iPos + lstrlen(pfr->lpstrFindWhat);
    
    	// Select the found text
    	SendMessage(hwndEdit, EM_SETSEL, iPos, *piSearchOffset);
    	SendMessage(hwndEdit, EM_SCROLLCARET, 0, 0);
    
    	return TRUE;
    }
    
    BOOL PopFindNextText(HWND hwndEdit, int * piSearchOffset)
    {
    	FINDREPLACE fr;
    
    	fr.lpstrFindWhat = szFindText;
    
    	return PopFindFindText(hwndEdit, piSearchOffset, &fr);
    }
    
    BOOL PopFindReplaceText(HWND hwndEdit, int * piSearchOffset, LPFINDREPLACE pfr)
    {
    	// Find the text
    
    	if (!PopFindFindText(hwndEdit, piSearchOffset, pfr))
    		return FALSE;
    
    	// Replace it
    
    	SendMessage(hwndEdit, EM_REPLACESEL, 0, (LPARAM)pfr->lpstrReplaceWith);
    
    	return TRUE;
    }
    
    BOOL PopFindValidFind(void)
    {
    	return *szFindText != '\0';
    }

    popfont.cpp


    #include <windows.h>
    #include <commdlg.h>
    #include "DetectMemoryLeak.h"
    
    static LOGFONT	logfont;
    static HFONT	hFont;
    static CHOOSECOLOR cc;
    static COLORREF crCustColors[16];
    
    
    BOOL PopFontChooseFont(HWND hwnd)
    {
    	CHOOSEFONT cf;
    
    	cf.lStructSize = sizeof(CHOOSEFONT);
    	cf.hwndOwner = hwnd;
    	cf.hDC = NULL;
    	cf.lpLogFont = &logfont;
    	cf.iPointSize = 0;
    	cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_EFFECTS;
    	cf.rgbColors = 0;
    	cf.lCustData = 0;
    	cf.lpfnHook = NULL;
    	cf.lpTemplateName = NULL;
    	cf.hInstance = NULL;
    	cf.lpszStyle = NULL;
    	cf.nFontType = 0;				// Returned from ChooseFont
    	cf.nSizeMin = 0;
    	cf.nSizeMax = 0;
    
    	return ChooseFont(&cf);
    }
    
    void PopFontInitialize(HWND hwndEdit)
    {
    	GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT),
    		(PTSTR)&logfont);
    
    	hFont = CreateFontIndirect(&logfont);
    	SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFont, 0);
    }
    
    void PopFontSetFont(HWND hwndEdit)
    {
    	HFONT hFontNew;
    	RECT rect;
    
    	hFontNew = CreateFontIndirect(&logfont);
    	SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFontNew, 0);
    	DeleteObject(hFont);
    	hFont = hFontNew;
    	GetClientRect(hwndEdit, &rect);
    	InvalidateRect(hwndEdit, &rect, TRUE);
    }
    
    void PopFontDeinitialize(void)
    {
    	DeleteObject(hFont);
    }
    
    BOOL PopFontChooseFontColor(HWND hwnd)
    {
    	cc.lStructSize = sizeof(CHOOSECOLOR);
    	cc.hwndOwner = hwnd;
    	cc.hInstance = NULL;
    	cc.lpCustColors = crCustColors;
    	cc.Flags = CC_RGBINIT | CC_FULLOPEN;
    	cc.lCustData = 0;
    	cc.lpfnHook = NULL;
    	cc.lpTemplateName = NULL;
    	return ChooseColor(&cc);
    }
    
    void PopFontSetFontColor(HWND hwndEdit, COLORREF * iColor)
    {
    	*iColor = cc.rgbResult;
    	InvalidateRect(hwndEdit, NULL, TRUE);	// Redraw the edit control . It will cause the WM_CTLCOLOREDIT message
    }



    popprint0.cpp

    #include <windows.h>
    #include "DetectMemoryLeak.h"
    
    BOOL PopPrntPrintFile(HINSTANCE hInst, HWND hwnd, HWND hwndEdit,
    	PTSTR pstrTitleName)
    {
    	return FALSE;
    }

    Detectmemoryleak.h

    #pragma once
    
    #ifndef _UT_DETECT_MEMLEAK_H  
    #define _UT_DETECT_MEMLEAK_H  
    
    #ifdef _DEBUG  
    #define new DEBUG_CLIENTBLOCK  
    #define DebugCodeCRT(m) {m;}  
    #endif  
    #ifdef _DEBUG  
    #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)  
    #else  
    #define DEBUG_CLIENTBLOCK  
    #endif  
    #define _CRTDBG_MAP_ALLOC  
    #include <crtdbg.h>  
    #ifdef _DEBUG  
    #define new DEBUG_CLIENTBLOCK  
    #endif  
    
    #endif _UT_DETECT_MEMLEAK_H  

    poppad.rc

    // Microsoft Visual C++ generated resource script.
    //
    #include "resource.h"
    
    #define APSTUDIO_READONLY_SYMBOLS
    /
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "afxres.h"
    
    /
    #undef APSTUDIO_READONLY_SYMBOLS
    
    /
    // English (United States) resources
    
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
    #pragma code_page(1252)
    
    #ifdef APSTUDIO_INVOKED
    /
    //
    // TEXTINCLUDE
    //
    
    1 TEXTINCLUDE 
    BEGIN
        "resource.h\0"
    END
    
    2 TEXTINCLUDE 
    BEGIN
        "#include ""afxres.h""\r\n"
        "\0"
    END
    
    3 TEXTINCLUDE 
    BEGIN
        "\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // Dialog
    //
    
    ABOUTBOX DIALOG 32, 32, 180, 100
    STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP
    FONT 8, "MS Sans Serif"
    BEGIN
        DEFPUSHBUTTON   "OK",IDOK,66,80,50,14
        ICON            "POPPAD",IDC_STATIC,7,7,20,20
        CTEXT           "PopPad",IDC_STATIC,40,12,100,8
        CTEXT           "Popup Editor for Windows",IDC_STATIC,7,40,166,8
        CTEXT           "(c) Charles Petzold, 1998",IDC_STATIC,7,52,166,8
    END
    
    PRINTDLGBOX DIALOG 32, 32, 186, 95
    STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
    CAPTION "PopPad"
    FONT 8, "MS Sans Serif"
    BEGIN
        PUSHBUTTON      "Cancel",IDCANCEL,67,74,50,14
        CTEXT           "Sending",IDC_STATIC,8,8,172,8
        CTEXT           "",IDC_FILENAME,8,28,172,8
        CTEXT           "to print spooler.",IDC_STATIC,8,48,172,8
    END
    
    
    /
    //
    // Menu
    //
    
    POPPAD MENU
    BEGIN
        POPUP "&File"
        BEGIN
            MENUITEM "&New\tCtrl+N",                IDM_FILE_NEW
            MENUITEM "&Open...\tCtrl+O",            IDM_FILE_OPEN
            MENUITEM "&Save\tCtrl+S",               IDM_FILE_SAVE
            MENUITEM "Save &As...",                 IDM_FILE_SAVE_AS
            MENUITEM SEPARATOR
            MENUITEM "&Print\tCtrl+P",              IDM_FILE_PRINT
            MENUITEM SEPARATOR
            MENUITEM "E&xit",                       IDM_APP_EXIT
        END
        POPUP "&Edit"
        BEGIN
            MENUITEM "&Undo\tCtrl+Z",               IDM_EDIT_UNDO
            MENUITEM SEPARATOR
            MENUITEM "Cu&t\tCtrl+X",                IDM_EDIT_CUT
            MENUITEM "&Copy\tCtrl+C",               IDM_EDIT_COPY
            MENUITEM "&Paste\tCtrl+V",              IDM_EDIT_PASTE
            MENUITEM "De&lete\tDel",                IDM_EDIT_CLEAR
            MENUITEM SEPARATOR
            MENUITEM "&Select All",                 IDM_EDIT_SELECT_ALL
        END
        POPUP "&Search"
        BEGIN
            MENUITEM "&Find...\tCtrl+F",            IDM_SEARCH_FIND
            MENUITEM "Find &Next\tF3",              IDM_SEARCH_NEXT
            MENUITEM "&Replace...\tCtrl+R",         IDM_SEARCH_REPLACE
        END
        POPUP "F&ormat"
        BEGIN
            MENUITEM "&Font...",                    IDM_FORMAT_FONT
            MENUITEM "Color...",                    IDM_FORMAT_COLOR
        END
        POPUP "&Help"
        BEGIN
            MENUITEM "&Help",                       IDM_HELP
            MENUITEM "&About PopPad...",            IDM_APP_ABOUT
        END
    END
    
    
    /
    //
    // Accelerator
    //
    
    POPPAD ACCELERATORS
    BEGIN
        VK_BACK,        IDM_EDIT_UNDO,          VIRTKEY, ALT, NOINVERT
        VK_DELETE,      IDM_EDIT_CLEAR,         VIRTKEY, NOINVERT
        VK_DELETE,      IDM_EDIT_CUT,           VIRTKEY, SHIFT, NOINVERT
        VK_F1,          IDM_HELP,               VIRTKEY, NOINVERT
        VK_F3,          IDM_SEARCH_NEXT,        VIRTKEY, NOINVERT
        VK_INSERT,      IDM_EDIT_COPY,          VIRTKEY, CONTROL, NOINVERT
        VK_INSERT,      IDM_EDIT_PASTE,         VIRTKEY, SHIFT, NOINVERT
        "^C",           IDM_EDIT_COPY,          ASCII,  NOINVERT
        "^F",           IDM_SEARCH_FIND,        ASCII,  NOINVERT
        "^N",           IDM_FILE_NEW,           ASCII,  NOINVERT
        "^O",           IDM_FILE_OPEN,          ASCII,  NOINVERT
        "^P",           IDM_FILE_PRINT,         ASCII,  NOINVERT
        "^R",           IDM_SEARCH_REPLACE,     ASCII,  NOINVERT
        "^S",           IDM_FILE_SAVE,          ASCII,  NOINVERT
        "^V",           IDM_EDIT_PASTE,         ASCII,  NOINVERT
        "^X",           IDM_EDIT_CUT,           ASCII,  NOINVERT
        "^Z",           IDM_EDIT_UNDO,          ASCII,  NOINVERT
    END
    
    
    /
    //
    // Icon
    //
    
    // Icon with lowest ID value placed first to ensure application icon
    // remains consistent on all systems.
    POPPAD                  ICON                    "poppad.ico"
    
    
    /
    //
    // DESIGNINFO
    //
    
    #ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO
    BEGIN
        "ABOUTBOX", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 179
            TOPMARGIN, 7
            BOTTOMMARGIN, 88
        END
    
        "PRINTDLGBOX", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 179
            TOPMARGIN, 7
            BOTTOMMARGIN, 88
        END
    END
    #endif    // APSTUDIO_INVOKED
    
    #endif    // English (United States) resources
    /
    
    
    
    #ifndef APSTUDIO_INVOKED
    /
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    
    
    /
    #endif    // not APSTUDIO_INVOKED
    
    


    resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Visual C++ generated include file.
    // Used by POPPAD.RC
    //
    #define IDC_FILENAME                    1000
    #define IDM_FILE_NEW                    40001
    #define IDM_FILE_OPEN                   40002
    #define IDM_FILE_SAVE                   40003
    #define IDM_FILE_SAVE_AS                40004
    #define IDM_FILE_PRINT                  40005
    #define IDM_APP_EXIT                    40006
    #define IDM_EDIT_UNDO                   40007
    #define IDM_EDIT_CUT                    40008
    #define IDM_EDIT_COPY                   40009
    #define IDM_EDIT_PASTE                  40010
    #define IDM_EDIT_CLEAR                  40011
    #define IDM_EDIT_SELECT_ALL             40012
    #define IDM_SEARCH_FIND                 40013
    #define IDM_SEARCH_NEXT                 40014
    #define IDM_SEARCH_REPLACE              40015
    #define IDM_FORMAT_FONT                 40016
    #define IDM_HELP                        40017
    #define IDM_APP_ABOUT                   40018
    #define IDM_FORMAT_COLOR                40019
    
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        110
    #define _APS_NEXT_COMMAND_VALUE         40021
    #define _APS_NEXT_CONTROL_VALUE         1001
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif
    



    运行结果


    可以改变和设置字体颜色




    11.3.2 Unicode 文件的读写操作

    在写入Unicode文件时先写入文件头  0xFEFF  表示此文本文件含有Unicode

    在读取时,使用IsTextUnicode函数来判断是否含有字节顺序标志,还会检测字节顺序标志是否反序的。 这意味此Unicode文本文件是在Macintosh或其他与Intel

    处理器字节顺序相反的机器上生成的。

    Unicode 转  ANSI

    WideCharToMultiChar

    WideCharToMultiByte(CP_ACP, 0, (PWSTR)pText, -1, pConv, iFileLength + 2, NULL, NULL);


    ANSI 转Unicode

    MultiByteToWideChar(CP_ACP, 0, (LPCCH)pText, -1, (PTSTR)pConv,iFileLength + 1);


    11.3.3 改变字体

    在处理WM_CREATE的时候,调用PopFontInitialize函数

    获取基于系统字体的LOGFONT结构,并由他创建一个字体,然后向编辑控件发送WM_SETFONT消息来设定新字体。

    GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT),
    (PTSTR)&logfont);


    hFont = CreateFontIndirect(&logfont);
    SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFont, 0);

    当用户选择字体时

    会初始化CHOOSEFONT结构,然后调用ChooseFont来显示字体选择对话框,用户按下OK此函数会返回TRUE

    然后POPPAD调用PopFontSetFont函数为编辑控件设置新字体,旧字体会被删除。


    最后在WM_DESTROY时,POPPAD会调用PopFontDeinitialize函数来删除PopFontSetFont最后创建的字体


    11.3.4 查找和替换

    FindText 和ReplaceText  使用FINDREPLACE的结构

    在查找和替换函数时由一些需要注意的事项。

    1, 他们使用的对话框是非模态对话框,这意味着当对话框在使用时消息循环应该调用IsDialogMessage函数。

    2,传递给FindText和ReplaceText的FINDREPLACE结构必须是静态变量。

    3,在FindText和ReplaceText时,他们与拥有他们的对窗口通过一种特殊的消息进行通信。这个消息对应值可以通过messageFindReplace = RegisterWindowMessage(FINDMSGSTRING); 来获取。

    在处理默认消息时,WndProc比较messageFindReplace, 消息参数lParam是一个指向FINDREPLACE结构的指针,该结构的Flags表示用户是否已经在用对话框来查找或替换文本,或正在关闭该对话框。

    通过调用PopFindFindText和PopFindReplaceText函数来实现查找和替换文本的功能。


    11.3.5 只调用一个函数的Windows程序

    Color3

    #include <windows.h>
    #include <commdlg.h>
    
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static CHOOSECOLOR cc;
    	static COLORREF crCustColors[16];
    
    	cc.lStructSize = sizeof(CHOOSECOLOR);
    	cc.hwndOwner = NULL;
    	cc.hInstance = NULL;
    	cc.rgbResult = RGB(0x80, 0x80, 0x80);
    	cc.lpCustColors = crCustColors;
    	cc.Flags = CC_RGBINIT | CC_FULLOPEN;
    	cc.lCustData = 0;
    	cc.lCustData = 0;
    	cc.lpfnHook = NULL;
    	cc.lpTemplateName = NULL;
    
    	return ChooseColor(&cc);
    }
    运行结果

    ChooseColor使用一个类型为 CHOOSECOLOR的结构和一个用来存储用户通过对话框选择的颜色含有16个DWORD值的数组。如果Flags字段
    设定CC_RGBINIT,那么rgbResult字段可以被初始化为锁要显示的颜色。一般情况下,rgbResult字段会被设置为用户选择的颜色。


    hwndOwnver 为NULL, 这是完全合法的。表示该对话框不属于任何窗口所有,会出现在windows任务列表中,并且对话框看上去和一般窗口狠相似。

    也可以在自己的程序对话框中使用这种技巧。Windows程序完全可以只创建一个对话框,并在该对话框过程中完成所有操作。

    展开全文
  • 对话框的窗口消息处理程序在Windows内部定义,这窗口过程调用您编写的对话框程序,把它所接收到的许多消息作为参数。下面是ABOUT1的对话框程序:BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,WPARAM wP.....

    您程序内的对话框程序处理传送给对话框的消息。尽管看起来很像是窗口消息处理程序,但是它并不是真实的窗口消息处理程序。对话框的窗口消息处理程序在Windows内部定义,这个窗口过程调用您编写的对话框程序,把它所接收到的许多消息作为参数。下面是ABOUT1的对话框程序:

    BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam)

    {

    switch (message)

    {

    case WM_INITDIALOG :

    return TRUE ;

    case WM_COMMAND :

    switch (LOWORD (wParam))

    {

    case IDOK :

    case IDCANCEL :

    EndDialog (hDlg, 0) ;

    return TRUE ;

    }

    break ;

    }

    return FALSE ;

    }

    该函数的参数与常规窗口消息处理程序的参数相同,与窗口消息处理程序类似,对话框程序都必须定义为一个CALLBACK(callback)函数。尽管我使用了hDlg作为对话框窗口的句柄,但是您也可以按照您自己的意思使用hwnd。首先,让我们来看一下这个函数与窗口消息处理程序的区别:

    窗口消息处理程序传回一个LRESULT。对话框传回一个BOOL,它在Windows表头文件中定义为int型态。

    如果窗口消息处理程序不处理某个特定的消息,那么它将呼叫DefWindowProc。如果对话框程序处理一个消息,那么它传回TRUE(非0),如果不处理,则传回FALSE(0)。

    对话框程序不需要处理WM_PAINT或WM_DESTROY消息。对话框程序不接收WM_CREAT消息,而是在特殊的WM_INITDIALOG消息处理期间,对话框程序执行初始化操作。

    WM_INITDIALOG消息是对话框接收到的第一个消息,这个消息只发送给对话框程序。如果对话框程序传回TRUE,那么Windows将输入焦点设定给对话框中第一个具有WS_TABSTOP样式(我们将在ABOUT2的讨论中加以解释)的子窗口控件。在这个对话框中,第一个具有WS_TABSTOP样式的子窗口控件是按键。另外,对话框程序也可以在处理WM_INITDIALOG时使用SetFocus来将输入焦点设定为对话框中的某个子窗口控件,然后传回FALSE。

    此外,对话框程序只处理WM_COMMAND消息。这是当按键被鼠标点中,或者在按钮具有输入焦点的情况下按下空格键时,按键控件发送给其父窗口的消息。这个控件的ID(我们在对话框模板中将其设定为IDOK)在wParam的低字组中。对于这个消息,对话框过程调用EndDialog,它告诉Windows清除对话框。对于所有其它消息,对话框程序传回FALSE,并告诉Windows内部的对话框窗口消息处理程序:我们的对话框程序不处理这些消息。

    模态对话框的消息不通过您程序的消息队列,所以不必担心对话框中键盘快捷键的影响。

    展开全文
  • 易语言WIN32程序设计对话框源码
  • Visual C++范例大全第6章 对话框程序设计栏源代码
  • DialogSheet:一Android库,用于创建完全材料设计的底部对话框,类似于Android Pay应用程序
  • 当您的程序显示一模态对话框时,使用者不能在对话框与同一个程序中的另一窗口之间进行切换,使用者必须主动结束该对话框,这藉由通过按一下「OK」或者「Cancel」键来完成。不过,在显示模态对话框时,使用者通常...
  • Q760642.zip windows程序设计 编写Windows窗口应用程序实现对话框与菜单的应用 https://ask.csdn.net/questions/760642 编写Windows窗口应用程序实现对话框与菜单的应用 1)编程实现如下应用程序,含有菜单,单击...
  • 编写Windows窗口应用程序实现对话框与菜单的应用 1)编程实现如下应用程序,含有菜单,单击“新建”时弹出新建对话框(非模态对话框),单击...教材是windows程序设计 (用WM_PAINT 这样的消息编写)。请看清楚要求
  • VB程序设计菜单对话框及多重窗体PPT教案学习.pptx
  • Visual Basic 程序设计基础:第七章 对话框和菜单程序设计.ppt
  • vc++对话框程序设计范例,有十几可运行的vc++对话框程序的范例,均可运行
  • 基于对话框程序设计计算器,叫你一步步实现计算器的编辑过程。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 134,357
精华内容 53,742
关键字:

怎么设计个程序对话框

友情链接: yi_chuan_suanfa.rar