不怕大家笑话,我通过国家水平考试高级程序员级,自认为在算法设计上没有问题,数据结构不能说精通也不会差,因为高级程序员考试对编程者的能力要求还是很高的(我自己认为),但是要命的是它还是考的是c\c++(dos环境),不考windows编程,以至于我现在连一个最基本的windows程序也不能理解,那怕是用向导建的一个什么也不会做的程序外壳,我也不能理解它是怎么回事,我曾经两次试过要过渡到windows编程,可是都没成功。(我并不是不懂c++,在VC中建个空的win32,我也能运用自如)。
    于是,我想请教各位高手们,当你们刚开始学windows编
程时是怎么学的,用的是什么书(给我推荐几本也行),还用,windows是通过消息传递来工作的,这我也知道,但我看消息都是定义好的,用大写字母表达的,有没有这样的书,能够介绍一下每一种消息,和它的表达方式呢?还有,能否推荐一本详细介绍windows API的书呢?另外我想请问几个具体一点的问题,书上说windows程序是从winmain开始运行的,可是我怎么也找不到这个函数,它在哪里呢?书上还说每一个对话框类都是由其成员函数create建立的,可是我还是找不到它在哪里!我用的是VC++6.0。

解决方案 »

  1.   

    MFC的main被包装起来了
    看看这篇文章,希望能对你有用
    MFC程序__从TextOut说起一
        该怎么开始说呢?首先这篇文章不是很标准的文章,就说说我怎么样开始真正使用VC 
    编程序的;然后面对的对象也不是已经在使用VC的战友们,目的或许是给还在VC门外徘徊 
    的,想学VC却不知如何下手一点借鉴。 
        仍然记得第一个知道有用的MFC函数是OnDraw(CDC *pDC),第一个使用的MFC函数是Te 
    xtOut(int x,int y,const CString& str)。那时候上算法分析,老师也算得上一个比较支 
    持VC的吧,因为他的语气让人总觉得他是比较高手的。 后来他给我们演示一个他 
    做的排序的算法,其实很简单,就是一个在从CView派生出来的视图里写出排序的结果,( 
    甚至连排序的那些数据都是写死在程序中的)。这算什么高深的VC程序啊!——当时看是 
    看过一些书,都是说些MFC 基础类库的,但是对这些东西都没有理性的认识,就算是这样 
    一个在View中写出“Hello World”来也不知道该往哪里写。这第一个TextOut(…)就写在 
    OnDraw函数里面,而OnDraw函数是在一个文档/视图(Doc/View)结构应用程序的xxxView.c 
    pp文件里面(VC->新建工程->MFC AppWizard->单个文档SDI或者多个文档MDI)。VC应用程 
    序向导生成的文件一大堆,没真正接触以前一看到就头疼,从这一堆文件中找到一个简单 
    入口点其实也挺不错的。找到没有? xxxView.cpp文件的56行,不信你看看(介绍用用Edi 
    tPlus)。添加TextOut后的代码如下: 
    void CAaaView::OnDraw(CDC* pDC) 

        CAaaDoc* pDoc = GetDocument(); 
        ASSERT_VALID(pDoc); 
        pDC->TextOut(100,100,"你好"); 

    我倒,一个代码一大堆的程序只有一行是我写的,各位看客要加上些其他如cout,printf之 
    类的代码我也不反对,不过在这里是不会生效的,至少现在不会。生成->运行,“你好” 
    出来了——空白包含“你好”的地方就是CxxxView起作用的地方。然后,希望加入一系列 
    排版得比较好的文字,就改动一下TextOut(int x,int y,const CString& str)中x,y的数 
    值,x和y分别表示输入点的横坐标和纵坐标,左上角为零点,向右向下递增。前面提到的 
    老师的排序输出就是这样做的。 
    知道了这一步,我想:不会吧,难道记事本那些编辑器都是要这样做出来,然后自己加入 
    字符处理的代码?不是的,在应用程序向导的最后一步,有个地方可以选择Base Class, 
    里面有CEditView(就是记事本用的),CFormView(有一个像对话框一样的背景,可以往上面 
    拖控件),CHtmlView(打开网页的,自己做网页浏览器哦,当然其实还是用的IE的组件), 
    CListView(效果如资源管理器右边显示文件列表),CRichEditView(类似Word的输入区,可 
    以修改字体属性等),CScrollView(和View一样的工作区,加入了滚动条控制,做图片编辑 
    的时候一般用这个),CTreeView(效果如资源管理器左边树形文件列表),另外在VC++.Net 
    中加入了CHtmlEditView,效果和FrontPage等网页编辑软件类似。另外,在使用Doc/View 
    结构的时候,第四步,点击高级按钮,可以设定应用程序默认打开的文件类型和后缀名。 为了继续分解、完善TextOut程序,先说说其他相关的内容: 
    1.    向导生成的MFC程序的基本结构及流程。刚开始学的时候,除了找到入口点,我更 
    希望的是了解一个MFC程序是怎样运行起来的。随便一种类型的MFC程序(doc/view结构,对 
    话框),打开以工程名称命名的cpp文件(CxxxApp的实现文件),一般都在第45行左右,可 
    以看到CxxxApp theApp; 。这里和控制台、win32程序不同,没有特定的main函数,一个对 
    象就是程序的开始,这也算是面向对象程序设计的一个特征吧,原来学过一阵(VC以前)JA 
    VA,发现他的应用程序对象的创建直接是在对象里面创建的,VC中能不能这样呢?发现是 
    不行,呵呵(要是行微软还不做进VC里面去,我这个认真呆)。反正这就是一个MFC程序的 
    生命之源(是不是有点夸张了)。这里构造了一个应用程序的对象,从这里开始,程序就 
    启动了,然后是CxxxApp类中的InitInstance()函数,进行一些初始化。对话框程序的话, 
    这里打开一个对话框;而文档/视图程序,这里构造一些可以使用的文档/视图模板(可以 
    通过AddDocument(…)添加多个模板,新建文档的时候会跳出窗口选择),并打开一个对应 
    主窗体CMainFrame。 
    (1) 多文档结构: 
                     CxxxApp(CWinApp)   → CMainFrame (CMDIFrameWnd) 
                      ↓↓               ↘                  菜单IDRXX 
               CMultiDocTemplate(模板1)  (模板2) … 
             ↙      ↘       ↓↘ 
      CxxxView → ← CxxxDoc ↓  CChildFrame(CMDIChildWnd) 
                      子窗体的菜单IDR_XXXTYPE 
    从上面可以看到主窗体有一个菜单,每个模板也有各自的菜单(菜单是模板构造函数的一 
    个参数),当主窗体加载模板的时候会自动用该模板的菜单替换原来的菜单。上面括号中 
    是各自的基类。从资料上可以看到CxxxView和CxxxDoc是关系及其紧密的两个类,View负责 
    用户界面的实现(所以OnDraw函数是在View类里,而不是Doc类里),Doc负责内容的实现。 
    用过其它的编程工具,对VC的这个机制有种感觉是增加了不少难度。但有些人或许感觉这 
    种对于在整个VC框架下编程是有帮助的。仁者见仁,智者见智了。 
    (2). 单文档结构: 
                     CxxxApp(CWinApp)   → CMainFrame (CFrameWnd) 
                      ↓↓               ↘               
               CSingleDocTemplate(模板1)  (模板2) … 
                 ↙      ↘      ↓↓ 
      CxxxView → ← CxxxDoc 子窗体的菜单IDR_MAINFRAME 
    单文档同样可以有多个模板,每个模板又有各自的菜单,那打开一个模板,再调用其它的 
    模板时会出现什么情况呢?新的独立的窗口跳了出来,当然这是用新模板的窗体,界面会 
    不一样。另外,如果关闭新的窗口不会对旧的窗口造成什么影响,如果第一个窗口关闭了 
    ,后面打开的所有模板的窗口也随之关闭。这是因为,第一个窗口才是主进程所在。学过 
    操作系统的大概都知道,除非你逃课,嘿嘿。 
    单文档和多文档有什么区别呢(前提没有使用多模板)?难道就是单文档只有一个客户区 
    (就像记事本种空白区域),多文档可以有多个客户区。当然不是,单文档,顾名思义就是 
    只有一个CxxxDoc对象,多文档就是有多个CxxxDoc对象。下面通过一个例子来比较一下。 做一个单文档程序,在CxxxDoc里面定义一个int nTest ,构造函数中nTest=0; 在OnNewD 
    ocument()函数中加入代码后如下: 
    BOOL CTest1Doc::OnNewDocument()//看函数就该知道新建文档的时候 
    {                                    //必须调用的 
        if (!CDocument::OnNewDocument()) 
            return FALSE; 
        CString str; 
        nTest++; 
        str.Format("nTest=%d,表示这个Doc类用了%d次",nTest,nTest); 
        MessageBox(NULL,str,"测试",MB_OK); 
        return TRUE; 

    做一个多文档程序,在同样的位置加入同样的代码。分别点击文件左上角的新建按钮,可 
    以发现单文档的程序每新建一次nTest就加1,而多文档程序中nTest始终为1。这说明单文 
    档新建的时候并没有使用一个全新的文档Doc对象,多文档程序中的则是一个新的Doc对象 
    。这同时给我们一个警示,单文档中如果加载了一些内容,新建的时候必须将这些内容重 
    置。 
    (3). 对话框程序。这是向导生成的最简单的MFC程序,包含的对象只有一个CxxxApp和一个 
    CxxxDlg。CxxxApp和前面两个MFC类型一样,是程序启动的根本,CxxxDlg则是对应对话框 
    的控制类。这个对话框呢!就是生成对话框应用程序的向导结束后在VC资源编辑区处于编 
    辑状态的窗体。对话框窗体又是怎样和CxxxDlg类联系的呢?偏题也不能偏得太远了,有机 
    会后面再说。 
     2. VC中使用的一般是匈牙利命名法,我说还不如看看别人怎么说的,下面是CSDN论坛中 
    一个帖子的说法: 
    /**************转帖部分开始*********************/ 
        匈牙利命名法 
    这个方法可能很多人都听说过,包括我在内的一些人也试图去使用它,可是还是觉得自己 
    的好,但是现在看来这种想法是错误的。再解释解释吧。这些符号可以多个同时使用,顺 
    序是先m_,(这上标记指成员变量)再指针,再简单数据类型,再其他。例如:m_lpszSt 
    r, 表示指向一个以0字符结尾的字符串的长指针成员变量。 a Array 
    b Boolean 
    by Byte 
    c Char //有符号型字符 
    cb Char Byte //无符号型字符(没多大用处) 
    cr ColorRef //颜色参考值 
    cx,cy Length of x,y (ShortInt) //坐标差(长度) 
    dw Double Word 
    fn Function 
    h Handle 
    i Integer 
    m_ Member of a class 
    n Short Integer 
    np Near Pointer 
    p Pointer lp Long Pointer 
    s String 
    sz String with Zero End //以字符'\0'结尾的字符串 
    tm Text //文本内容 
    w Word 
    x,y Coordinate //坐标 类名一般没有说明字符,例如theApp. 用在其他类中加m_就行。要注意的是:某些类也有 
    类似于匈牙利命名法的缩写。例如:CStatusBar m_wndStatusBar;这里的wnd表示窗口类, 
    但是这种命名法不是标准的匈牙利命名法的一部分。 
    /***************转帖部分结束*******************************/ 
      

  2.   

    另外还有一些个人也觉得是比较好的编程风格有:a。函数名称尽量用英语单词,不会就用 
    金山词霸,或者东方快典(我常备东方快典,呵呵),尽量用函数名称代替注释,而且VC 
    中比较规范的是函数名称每个单词第一个字母用大写。b。类的名称特定位置包含该控件的 
    名称的缩写(如上面说到的类似匈牙利命名法的缩写),具体什么位置,就看着办吧!MF 
    C类库中都是放在最后面如CxxxView,CxxxApp等等,这里我有点奇怪为什么不用CViewXXX 
    ,CAppXXX呢?特别是文件一大串的时候类视图和文件视图都是按照字母排序的,这样按照 
    特定类的类型查找将更方便一些,微软做VC的时候是怎么想的呢!各位感觉怎样。第一个 
    字母C好像是MFC类的特称,就和Delphi的产品一样类库都用T开头。用不用,看多了一样顺 
    眼。当然,为了和广大的VC程序员结为一体,老老实实按照CxxxView还是没错的。 
     3.TextOut是不是随便一个地方都可以用的答案是:看怎么用法。这是对只做过程程序设 
    计的人说的。其实了解这个函数的用法的时候是在MFC程序中都可以用它,有时候要看看是 
    什么效果。TextOut是CDC类中的一个函数。DC(Device Context)中文是设备上下文,这和 
    控制台程序中的Printf函数有类似的解释。上课的时候,老师说Printf的执行结果是将字 
    符串从标准输出设备中输出,而我们不用管这个设备是什么,一般来说Printf的标准输出 
    设备默认指向命令行模式下那个黑黑的冬冬,当然有时候不是。比如上节课操作系统老师 
    说的,在运行包含输出的控制台程序名后面加上 > c:\tem.txt 的管道命令,这样输出结 
    果就到c:\tem.txt里去了。DC也差不多,在不同的情况下有不同起作用的对象,但总的来 
    说,我们可以当它是一块画布,专门用来画东西的,和其他面向对象程序语言中的Canvas 
    是殊途同归的。所不同的是类库内容丰富程度不同,简易程度也不同。在其他面向对象语 
    言中也可以使用DC,不过一般不是基础类库中的CDC,而是用DC的句柄HDC(C++ Builder  
    5.0里面也可以用MFC编程)。在View类中OnDraw的CDC *pDC作用效果就是在客户区操作, 
    画图,写字等,OnPrint的CDC *pDC则效果体现在打印的纸上了。另外每一个从CWnd派生出 
    来的几CWnd都可以取得对应的DC,专门用来绘制对应窗体的,操作这个DC就可以在窗体上绘制东西 
    了。对应命令是CDC *pDC=pWnd->GetDC();,据MSDN介绍,窗口类的DC最多只能同时被调用 
    (GetDC)五次,所以每次使用GetDC()以后都要调用pWnd->ReleaseDC(pDC)释放调用,以免 
    影响其它程序调用。CClientDC是CDC的派生类,可以通过CClientDC dc(CWnd* pWnd)来直 
    接获得窗口DC。 
    好了,现在我们来继续来完善、分解上面的TextOut程序。 
    如果想输出的是数字该怎么办呢?在MFC中有一个很方便的字符串类CString,所以不用像 
    C中仔细考虑分配内存、数字到字符串转换的问题,CString通过格式化字符串函数Format 
    来实现各种类型数据到字符串的转换,用法和sprintf函数类似: 
        CString Str; 
        int nInt=19;float fFloat=0.3f; CString strString="hello";char p[]="hello2" 

        Str.Format("%d,%f,%s,%s",nInt,fFloat,strString,p); 
        ::AfxMessageBox(Str); 
    CString对象怎么转换成其他的数据类型呢?我暂时知道的是先转换成char* p类型,然后 
    通过运行库(Run-Time Library)的函数来转换,一些例子如下: 
        CString str="3.0"; 
        char *p=str.GetBuffer(str.GetLength()+1);     
        double tf=atof(p);     
        int ti=atoi(p); 
        long tl=atol(p); 
        TRACE("tf=%f,ti=%d,tl=%ld\n",tf,ti,tl); 
        str.ReleaseBuffer(); 
    高级一点的字符串到数值的转换函数有strtol(长整型),strtod(double型)<stdlib.h 
    >,值得一说的是strtol可以支持不同进制字符串到整型的转换。数值转换成字符串则用_ 
    itoa, _ltoa, _ultoa等库函数,这些函数都支持转换成不同进制格式的字符串。具体怎么 
    时候还是自己动手丰衣足食咯。 
    好了,暂时先说这些吧!说得太多,看也懒得看了。如果有必要,下次应该说说如何在不 
    同地方使用DC。可能比较烂,各位高手见笑了。^_^ 
      

  3.   

    hahu(网痞 -- 勿近)牛人