既然在WinMain的前面声明了Wndproc(而且在Winmain后面定义了),为什么在Winmain中用一个指向这个函数的指针?直接调用不就行了吗?既然WinMain的返回值是int型,为什么还要加上WINAPI修饰?就好像: int vector main一样荒唐!在C++中没有见过这种用法啊!为什么有两个修饰词?static TCHAR szAppName[] = TEXT ("HelloWin") 可不可以改成static CHAR szAppName[] ="HelloWin"? WinMain的最后返回一个msg.wParam,并不是一个int型啊!这里:GetClientRect (hwnd, &rect) ;
既然RECT结构型都用了引用&rect,为什么HWND不用引用&hwnd呢?“WNDPROC  lpfnWndProc”既然“lpfnWndProc”是指向函数的指针,是不是就等于"WNDPROC (*lpfnWndProc)()"?这几个问题请高手指点!

解决方案 »

  1.   

    WINAPI 就是stdcall方便而已,windows 下有pascal stdcall 等调用方式,这与一个函数是否自己清清除stack,WINDOWS平台的api调用都必须使用stdcall方式。不明白自己看WIN32汇编。
    wndproc是给WINDOWS系统调用的,这样设计是有他的理由的,每个程序只能有一个WINPROC函数处理消息,消息机制是多进程的基础。
    不明白自己看Programming Windows.
    不要小瞧了微软的设计师们,他们大多是天才。
      

  2.   

    是咯,在winasm32中,winmain并不是必需的咯,你可以在汇编程序中直接写winmain里面的代码。呵呵
    -------------------------------------------------------------------------
    PASCAL约定和C约定正好相反,它规定参数是从左向右传递,由被调用者恢复堆栈。Win16采用了PASCAL约定, 因为PASCAL约定产生的代码量要小。当不知道参数的个数时,C约定特别有用。如在函数wsprintf () 中, wsprintf预先并不知道要传递几个参数,所以它不知道如何恢复堆栈。STDCALL是C约定和PASCAL约定的混合体,它规定参数的传递是从右到左,恢复堆栈的工作交由被调用者。Win32只用STDCALL约定,但除了一个特例,即:wsprintf。C 编译器要求您的源代码有必须有一个函数叫 WinMain。否则 C 无法知道将哪个函数和有关的前后代码链接。相对C,汇编语言提供了较大的灵活性,它不强行要求一个叫 WinMain 的函数。
    -----------------------------------------------------------------------
    在连接阶段,链接器需要把启动代码和用户的代码组合成可执行文件,而启动代码里面就有call main
    等等
    这是main/winmain为什么必须存在的原因呵呵
      

  3.   

    C语言的启动代码如下: 
    ; tcstart.asm 
    ; for d000 code only, external eprom on memory card 
    ; FOR PC ROM  
    extrn  _main:far;  /*  说明外部的C语言的MAIN() 函数,这也是 C 语言为什么非要从MAIN()开始的原因 */ 
    _text segment byte public "CODE" ; /* C语言生成的代码段 */ 
    _text ends 
    _textend segment para public "CODEEND";  /* 代码段的结束段 */ 
    _textend ends 
    _data segment para public "DATA"; /* C语言生成的初始化数据段 */ 
    _data ends 
    _dataend segment para public "DATAEND"; /* 初始化数据段的结束段 */ 
    _dataend ends 
    _bss segment para public "BSS"  ;/* C语言生成的非初始化数据段 */ 
    _bss ends 
    _bssend  segment byte public "BSSEND";/* C语言生成的非初始化数据结束段 */ 
    _bssend  ends 
    _stack segment para stack  "STACK" ; /* 堆栈段 */ 
    _stack ends 
    DGROUP group _DATA, _DATAEND, _BSS, _BSSEND /* 把数据的段构成一个组,代码连在一起 */ 
    CGROUP group _TEXT, _TEXTEND /* 把代码的段构成一个组,代码连在一起 */ 
    _TEXT segment    ; /* 代码段 */ 
    assume CS:CGROUP, DS:DGROUP, ES:DGROUP, SS:_STACK start: cli            ; disable interrupts 
    mov ax, _STACK ; initialise stack 
    mov ss, ax 
    mov ax, offset stackend 
    mov sp, ax 
    mov ax, seg _BSS ; /* BSS SEG CLEAR */ 
    mov es, ax 
    mov cx, offset DGROUP:endbss 
    mov di, 0    
    mov ax, 0 
    rep stosb ; write to ES:DI 
    mov ax, seg DGROUP  ;初始化数据段 
    mov es, ax ; point ES to _DATA 
    mov cx, offset DGROUP:enddata 
    mov si, 0 
    mov di, 0 
    assume ds:CGROUP 
    mov ax, seg _TEXTEND:codeend 
    inc ax 
    mov ds, ax ; point DS to _CONST 
    rep movsb ; copy _CONST to _DATA 
    push es ; point DS to _DATA 
    pop ds 
                                 ;下面内容非PC 机可以不要 
    mov al, 80h      ; enable NMI 
    out 0a0h, al 
    mov al, 0bch     ; enable 8259 PIC  1011-1100 (irq0,1,6 enabled) 
    out 21h, al 
                                 ;上面内容非PC 机可以不要 
    sti ; enable interrupts 
    call _main   ; CALL C MAIN()  
    jmp start   ; 
    _TEXT ends 
    _TEXTEND segment 
    public codeend 
    db 16 dup(?) ; a paragraph, thus _CONST is one byte more 
    codeend label byte 
    _TEXTEND ends 
    _STACK segment 
    db 1024 dup ("STACK");/* 预留的堆栈空间 */ 
    stackend label word 
    _STACK ends 
    _BSSEND segment 
    public endbss 
    endbss label byte 
    _BSSEND ends 
    _DATAEND segment 
    public enddata 
    enddata label byte 
    _DATAEND ends 
            end 
    编译连接: 
    tasm /mx tcstart 
    bcc -a- -c -f- -G- -K -B -ml -M -N- -O- -r- -v- -y- -Z- -S -O-  1.c 
    tlink /m tcstart  1 tclib,  1,  1 呵呵
      

  4.   

    你们只回答了我第一个问题啊!这些怎末解释?“WinMain的最后返回一个msg.wParam,并不是一个int型啊!这里:GetClientRect (hwnd, &rect) ;
    既然RECT结构型都用了引用&rect,为什么HWND不用引用&hwnd呢?“WNDPROC  lpfnWndProc”既然“lpfnWndProc”是指向函数的指针,是不是就等于"WNDPROC (*lpfnWndProc)()"?”
    哪朋友能指点一下?
      

  5.   

    在以前的版本,msg.wParam是word型,但是到了后来,变成了long型,并不是你说的int型。
      

  6.   

    typedef unsigned int        UINT;
    typedef UINT WPARAM;TCHAR 不能换成char ,是为了使用unicode
      

  7.   

    为什莫不返回int型的?WinMain不是用int修饰的吗?GetClientRect (hwnd, &rect) 中的hwnd为什麽不用引用?
      

  8.   

    关于WinMain()的返回值,msg.wParam的类型是WPARAM,在32位的系统中WPARAM就是int,同为4字节,其实这个时候msg.wParam就是0,你要是愿意写return 0;也可以.GetClientRect函数的原型是
    GetClientRect(HWND hWnd,LPRECT rc);
    所以在使用中必须用
    RECT rc;
    GetClientRect(hWnd,&rc);
    int i=rc.right;这个和hWnd要不要用call-by-reference一点儿关系都没有.早就看到了这个帖,总觉得楼主问问题时一副"他妈的,这是怎回事?"的口气,所以就放下了.后来看到有人up,想想可能对其他人或许有些参考作用,才写了这几句.敬请楼主"视而不见".
      

  9.   

    函数GetClientRect(HWND hWnd,LPRECT rc)的第一个参数是个句柄,说白了就是个指针,
    如果,对指针在使用&hWnd话,那传递给GetClientRect()函数的就是hWnd 这个指针变量的地址了,而不是这个指针变量所指向的内容了。以上是俺的一点浅显认识,还望各位前辈指教。。
      

  10.   

    to Zark!
       C++板块是有不少骂人的!但和我无关,“总觉得楼主问问题时一副"他妈的,这是怎回事?"的口气,”这句话毫无根据!
      

  11.   

    短信收到,一并在此回复.对于你的帖子我的确是这样感觉的,至于有无根据,可以调查一下.楼主如果有空,可以发贴征求一下大家的意见,不妨把你的问题原封不动搬上去,然后取个名字叫"请问这个发帖人在发问是什么样的态度?".其次,我说的"他妈的,这是怎回事?"只是形容你的口气,而不是真的指责你在骂人.你发帖提问,当然不会骂人在先,不然谁还会回答你的问题呢.我只所为你的口气不对,是从下列片断中得来的.
    1. 为什么在Winmain中用一个指向这个函数的指针?直接调用不就行了吗?(如果直接调用就是不WINDOW 编程了,引自"rivershan(笨猫)",从此看来你的WINDOW编程的初学者).
    2. 为什么还要加上WINAPI修饰?就好像: int vector main一样荒唐!(如果你是初学者,就不要指责一个已经几十年的函数是荒唐的,说句实话,第一次读你帖子到这儿时,我首先感到就是,鲁班门前又来了一个).
    3. 在C++中没有见过这种用法啊!为什么有两个修饰词?(读到这里,更有一种感觉,楼主仿佛已经通晓C++,现在看到了一个C++没有的东东,于是唐吉诃德挺起了长矛,向...冲去).
    4. WinMain的最后返回一个msg.wParam,并不是一个int型啊!(再次被楼主深深地感动,我已经看到多少个感叹号,多少个反问号?天啊,莫不是屈夫子又回来了)再次声明,我指责的是你的"口气"或者是说"态度",我并没有在诬蔑你骂人.我认为一个初学者在发现问题后经过思考,再到这里提问,应该本着一种请教的态度.最后声明,楼主是请高手指教的.我不是高手,我不是指教,我只是"唠叨两句".
      

  12.   

    “再次声明,我指责的是你的"口气"或者是说"态度",”我知道,但是我的口气也没有!我认为知识是高尚的,是宝贵的,我尊重知识,你的口气是说我是冲着知识来得?!你有什麽资格评口气判断人?那麽多人回复我的问题,怎莫但你认为我是这种口气?别人为什莫都虚心回答?我认为你这个人一点也不谦虚的人,我宁可向“commandos(孤独求胜) ”这样虚心的人求教!CSDN热心的高手多的是,我不缺你回答!单评知觉就判断人,而且你的直觉是错的!用感叹号说明我求题心切,你现在比别人(可能)多懂点知识了,我就不信你出学的时候没问过题,如果MSDN能解决一切问题,那要CSDN有什莫用?!看来你是那种单凭想象就简单判断事务的人,在现实社会中一定得罪不少人,属于永远交不到朋友的那种人!
      

  13.   

    我倒是有不同的看法,上面的帖子我都看了,楼主的口气的确是求知心切(只是问题有点初级),我倒认为Zark损人损得很厉害,这样对一个初学者的成长是不好的。单凭主观判断本来就是没有根据,如果在公司中敢这样唠叨,我相信那这个人也是吃不开的吧。To zark:说话应有点分寸,毕竟能回答问题得人太多了,你站在楼主的角度想想就能理解了。To jcreatorqijiashe:我相信这只是误会,你后来讲的又严重了,我认为你问的这几个问题是可以用MSDN解决的,但一定要耐心。
    最后说一句,CSDN是大家讨论知识学习的地方,不是辩论的战场,希望大家能共同珍惜维护这样一个好的学习环境,呵呵...多说了几句,不会介意吧 :)