多年来windows编程的一些一知半解的问题(100分)

Z

zjc

Unregistered / Unconfirmed
GUEST, unregistred user!
这些我在书上都找不到直接的答案-欢迎讨论!
1.DispatchMessage(&msg)函数是如何工作的,是直接调用本窗口的处理过程WndProc还是向消息队列发送消息再由windows去调用相应窗口的WndProc;如果是后者那么也可以通过这个函数向其他进程发消息了?
2.一个应用程序的各种子窗口(如按钮、编辑框等)在应用程序启动时也都象主窗口那样先注册吗RegisterClass(&wndclass)?到底这个注册操作有什么用呢,是象声明变量那样申请内存空间吗?
3.假定2—每个子窗口都注册并创建了,都有各自的handle(hwnd),那个每个子窗口也都有各自的消息处理过程WndProc吗,还是将用户操作消息统一发到主窗口的消息队列里由主WndProc处理。——我原来的理解是后者,但看到delphi里:控件类都有WindowProc属性,且帮助里说可以临时替换窗口处理过程,我就有些胡涂了。
先想这么多,请大家不吝赐教。
 
1 是直接调用本窗口的处理过程WndProc ,向其他进程发消息还是send(post)message吧
2 这么说吧,你要创建一个form是吧,vcl是再TForm里面设置属性,可windows不知道什么TForm阿,于是就要创建一个“属性集”wndclass 还要为这个属性集起个名字,然后告诉windows,这种form我注册了,以后创建这种类型的窗口你老别发昏。具体创建窗口的时候第一个参数不就是window class name啊。。。
3 vcl封装的是很优秀很优秀的啦比如TBtn,TRadioBtn什么的,再windows 里它们全部都是button类的 ,windows预先注册了一些class,比如btn阿,listbox阿。这些都不需要注册可以直接createwindow的.一般每一个窗口对应一个窗口过程,所以他们当然有自己的WndProc,win32可以通过子类化技术重新定向WndProc的地址,就是setwindowlong
 
也有人说是每个窗口类共用一个处理过程,不过我觉得似乎不应该这样。
 
我也在想这几个问题
 
其实 从 wincontrol 继承的  所有控件 都和 tform 差不多 . 多可以像tform 一样
 
第一个问题,DispatchMessage将消息分发到消息队列,在消息发生之时,操作系统已经根据当时状态,为它标明了所属窗口,而窗口所属的窗口类也已经明白标示了窗口函数。这样,轮到消息处理时,系统自然知道它属于那个窗口,由那个窗口过程处理。
 
第二个问题上面几乎已经回答了,‘而窗口所属的窗口类也已经明白标示了窗口函数’这就
是它的作用。看一个子窗口创建的代码
hWndEdit2=CreateWindow("EDIT",NULL,
WS_CHILD|WS_VISIBLE|WS_BORDER|
ES_LEFT|ES_AUTOHSCROLL,
0,0,0,0,
hWnd,
(HMENU)IDE_EDIT2,
hInst,
NULL);
//创建编辑框子窗口2
其中的hWnd是当前窗口句柄,说明这个子窗口是属于当前窗口的。故它不用再注册了,虽然它也算是一个窗口。
 
子窗口共用一个窗口过程,用case语句判断应该处理那个消息。
 
谢谢各位,基本明白了。不过我想验证一下同一类窗口共用一个窗口处理过程。是否能得到这样的效果:比如我用setwindowlong改变了button类的处理过程——比如点击时红一下。那么是否屏幕上的所有按钮再点击时都变成了这个效果。
谁能帮我写出这个例子,c mfc delphi语言都可以。 万分感谢!
 
1.DispatchMessage是一个API函数,处于User32单元,User32.dll管理着系统里所有的窗口对象,所以它知道该调用那个窗口的窗口函数.
2.每一类窗口创建前都需要注册.有点类似与我们Delphi里Type里定义的类,然后才能
创建这个类的对象(只是一个比方).每一类窗口在创建后的窗口函数确实是一样的,函数地址在注册窗口类的时候指定。
3.VCL控件都有自己的WndProc过程,不过这过程可能调用主窗口类的方法。
setwindowlong 会改变一窗口的窗口过程,但同类窗口的窗口过程不会因此改变。
要作到这一点,要调用SetClassLong
 
每一类窗口在创建后的窗口函数确实是一样的,函数地址在注册窗口类的时候指定
setwindowlong 会改变一窗口的窗口过程,但同类窗口的窗口过程不会因此改变。
要作到这一点,要调用SetClassLong
===============================================================================
听着有些矛盾,这怎么理解?
 
第一个问题我试验过了,结论如下:
DispatchMessage(&msg)中,msg.hWnd并非不可替换。可以替换为NULL,在我的程序中可以继续运行,也可以替换为本窗口hWnd (m_hWnd)(等于白做),也能运行;不能替换成其他窗口的hwnd,否则报内存错误。可见DispatchMessage(&msg)不是发送消息给系统。使我一直产生此疑惑的是很多书上有类似描述:
DispatchMessage (&msg)
又將msg結構回傳給Windows。然後,Windows將該訊息發送給適當的視窗訊息處理程式,讓它進行處理。這也就是說,Windows將呼叫視窗訊息處理程式。在HELLOWIN中,這個視窗訊息處理程式就是WndProe函式。——见Programming Windows程式開發設計指南
但也不能简单认为就是直接调用本窗口的处理函数WndProc
——6p14的说法不恰当,可能也是和我原来类似的想法。
 
关于同一类窗口共用处理过程做了一个验证:
方法如下:在一个对话框上放置三个按钮,对其中一个按钮使用SetWindowLong、SetClassLong使其处理过程改为自己的函数,再看另外两个按钮是否发生相同的变化。结果表明,SetWindowLong只能影响第一按钮的反应,其他两个不变。SetClassLong使得另外两个按钮发生部分改变,并非预想的结果——确切的说是影响了MessageBox弹出的MB_OK按钮。所以根据我的理解最终结论如下:
在SDK层,各子窗口的确是共用一个处理过程,这可以参见windows C 程序的例子。封装后的控件类却不一定使用同一个处理过程——注意是同一个不是说同一类(不论是VCL的TButton还是MFC的CButton)或者说一定不是吧。这就解释了SetWindowLong后各按钮仍然保持独自的响应特征。但可能最基本的特性(比如显示按下状态等)仍是通过调用最基本类的过程完成的。所以使用SetClassLong后能影响多个控件。但建议在没有完全搞清楚各控件运行机制前不要轻易使用这个调用,可能结果并不是我们要的。
 
多人接受答案了。
 
你的理解是正确的,VCL调用API createwindowex创建窗口后立刻用MakeObjectInstance
方法替换其窗口过程为自己的MainWndProc方法,MainWndProc 方法仍然后调用远来窗口一
默认方法DefWndProc来处理一些消息。
 
顶部