几个问题都是针对 VC6.0 下的 WIN32 API 工程。1、我自己编写了一个类,并仿造MFC那样使用了.h 和.cpp两个文件分别作为类的声明和类的具体实现,然后在工程中使用该类,结果链接错误。然后我仿造MFC,把stdafx.h和stdafx.cpp两个文件拷了过来,并在自定义类的.cpp文件中加入了对stdafx.h的包含,然后编译、链接、运行都正常了,类可以正常使用!请问为何会出现这样的问题,以及stdafx.h和stdafx.cpp在工程中起什么作用!2、我用CreateWindow创建一个父窗口,然后又在其上用CreateWindow创建了一个子窗口,问题是当该子窗口有自己的标题栏时其怎样都不能得到输入焦点,SetFocus似乎不起作用!而在该子窗口无标题栏时,子窗口可以获得输入焦点,并得到键盘输入消息。请问为什么含有标题栏子窗口为什么不能得到输入焦点,怎样才能解决这个问题。3、在某教材上的窗口过程函数中看到如下的代码片段:
case WM_PAINT:
InvalidateRect(hwnd,NULL,TRUE);
BeginPaint(...);
... ...
EndPaint(...);
教材解释:使整个窗户区无效,从而可以在处理消息时在无效区域以外绘制!
我的理解:当窗口过程被调用并执行到“case WM_PAINT”,WM_PAINT消息已从消息队列移除,此时使用InvalidateRect(hwnd,NULL,TRUE)将促使一条新的 WM_PAINT 消息被放入进程的消息队列,进而使进程陷入永无止境的死循环中。
请指正我的想法错在哪!4、已知:
#define MAKEINTRESOURCE(i) (LPTSTR)((DWORD)((WORD)(i)))
LoadIcon(hInstance,MAKEINTRESOURCE(...));
教材讲解:如果函数的第二个参数的高字为零,那么低字就为图标的数字标识符。
我想问一个对整数数值i的变换!首先“((WORD)(i))”,应该是将该数值存储为一个字长度吧,在win32中也就是4B,相当于"int",然后是"((DWORD)((WORD)(i)))",从而将对其的存储转化为双字(8B),再然后我就不太明白了,宏定义然后使用了“LPTSTR”,这是返回前面转化几次后得到的结果的地址呢,还是把前面的结果作为双字长临时对象付给函数呢?根本教材的讲解应该是后者吧?可这样的话---LPTSTR是32位指针值呀!!!
希望各位大侠不吝赐教,在下先真诚的谢谢了!

解决方案 »

  1.   

    1.stdafx.h和stdafx.cpp并不会影响什么,你只要改一下编译选项,将stdafx那个选项去掉就好了
      

  2.   

    1.stdafx.h和stdafx.cpp可有可无。
    2.你的子窗口类属性设置对不对。
    4.LPTSTR是宽字符串指针。LoadIcon(hInstance,str);str为LPTSTR类型。
      

  3.   

    感谢两位!请问"hhyytt",关于问题4,我随便取一个整数,比如说1,MAKINTRESOURCE(1)最终结果是不是一个指向值为0X0000000000000001的存储区域的32位指针?对于子窗口,是先注册窗口类再创建子窗口的,能告诉我是哪个赋值不合适吗?
      

  4.   

    1、stdafx.h 是与编译头文件,你如果没用MFC类,也可以#include他,但要在工程设置里改为不使用预编译头文件。
      

  5.   

    1、stdafx.h 是与编译头文件,你如果没用MFC类,也可以不#include他,但要在工程设置里改为不使用预编译头文件。
      

  6.   

    关于3调用BeginPaint(...);
    EndPaint(...);可以使无效区域变成有效如果你没有BeginPaint和EndPaint,那么就会出现你说的死循环
    可以参考windows程序设计 这本书的69页有描述
      

  7.   

    谢谢毛毛!你看这样理解对不对:程序运行到 “case WM_PAINT”时,WM_PAINT 消息已被移除,但无效区域仍然是无效的,这时候使用“InvalidateRect(hwnd,NULL,TRUE)”语句将促使 WINDOWS 将无效区域扩大到整个客户区,并在进程的消息队列加入新的 WM_PAINT 消息;程序执行到
    “BeginPaint(...);
     ... ...
     EndPaint(...);”
    的时候,无效区域消失,消息队列中的 WM_PAINT 消息被移除!
      

  8.   

    重新看了一下书,又看了一下msdn
    我的理解,是,在这里InvalidateRect(hwnd,NULL,TRUE)并没有发送WM_PAINT
    它只是改变无效区的大小msdn上的The invalidated areas accumulate in the update region until the region is processed when the next WM_PAINT message occurs or until the region is validated by using the ValidateRect function. The system sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window.因为在之前,已经有了更新区域update region ,所以窗口收到了 WM_PAINT message 
    然后你用invalidated ,改变了更新区,或者说是无效区的大小~~
      

  9.   

    去察看一下windows程序设计
    的第67页是因为有无效区的存在,才会产生print消息如果在处理WM_PAINT
    时,另一个区域也变无效了,那么会重新计算无效区,不会把多个WM_PAINT
    消息放队列里的